From 635b46e0cfe492043a6031e6cf589cddc760ee07 Mon Sep 17 00:00:00 2001 From: Eltik Date: Tue, 5 Sep 2023 15:56:37 -0400 Subject: [PATCH 01/77] Use bun --- anify-backend-recode/.eslintignore | 2 + anify-backend-recode/.eslintrc | 33 + anify-backend-recode/.gitignore | 169 ++ anify-backend-recode/.prettierignore | 12 + anify-backend-recode/.prettierrc.json | 13 + anify-backend-recode/README.md | 15 + anify-backend-recode/db.sqlite | Bin 0 -> 36864 bytes anify-backend-recode/package-lock.json | 43 + anify-backend-recode/package.json | 27 + .../src/database/impl/create.ts | 124 ++ anify-backend-recode/src/database/impl/get.ts | 11 + .../src/database/impl/search.ts | 20 + .../src/database/impl/searchAdvanced.ts | 64 + .../src/database/impl/seasonal.ts | 51 + anify-backend-recode/src/database/index.ts | 93 + anify-backend-recode/src/helper/index.ts | 23 + anify-backend-recode/src/index.ts | 10 + anify-backend-recode/src/lib/event.ts | 14 + anify-backend-recode/src/lib/executor.ts | 163 ++ anify-backend-recode/src/lib/impl/entry.ts | 28 + anify-backend-recode/src/lib/index.ts | 0 anify-backend-recode/src/types/enums.ts | 130 ++ anify-backend-recode/src/types/types.ts | 192 ++ anify-backend-recode/tsconfig.json | 22 + anify-backend/package-lock.json | 1807 +---------------- anify-backend/package.json | 4 +- .../src/mapping/impl/anime/nineanime.ts | 3 +- anify-backend/tsconfig.json | 1 + anify-backend/yarn.lock | 860 +------- 29 files changed, 1369 insertions(+), 2565 deletions(-) create mode 100644 anify-backend-recode/.eslintignore create mode 100644 anify-backend-recode/.eslintrc create mode 100644 anify-backend-recode/.gitignore create mode 100644 anify-backend-recode/.prettierignore create mode 100644 anify-backend-recode/.prettierrc.json create mode 100644 anify-backend-recode/README.md create mode 100644 anify-backend-recode/db.sqlite create mode 100644 anify-backend-recode/package-lock.json create mode 100644 anify-backend-recode/package.json create mode 100644 anify-backend-recode/src/database/impl/create.ts create mode 100644 anify-backend-recode/src/database/impl/get.ts create mode 100644 anify-backend-recode/src/database/impl/search.ts create mode 100644 anify-backend-recode/src/database/impl/searchAdvanced.ts create mode 100644 anify-backend-recode/src/database/impl/seasonal.ts create mode 100644 anify-backend-recode/src/database/index.ts create mode 100644 anify-backend-recode/src/helper/index.ts create mode 100644 anify-backend-recode/src/index.ts create mode 100644 anify-backend-recode/src/lib/event.ts create mode 100644 anify-backend-recode/src/lib/executor.ts create mode 100644 anify-backend-recode/src/lib/impl/entry.ts create mode 100644 anify-backend-recode/src/lib/index.ts create mode 100644 anify-backend-recode/src/types/enums.ts create mode 100644 anify-backend-recode/src/types/types.ts create mode 100644 anify-backend-recode/tsconfig.json diff --git a/anify-backend-recode/.eslintignore b/anify-backend-recode/.eslintignore new file mode 100644 index 0000000..7d671e7 --- /dev/null +++ b/anify-backend-recode/.eslintignore @@ -0,0 +1,2 @@ +/dist +**/*.js \ No newline at end of file diff --git a/anify-backend-recode/.eslintrc b/anify-backend-recode/.eslintrc new file mode 100644 index 0000000..13b5ac5 --- /dev/null +++ b/anify-backend-recode/.eslintrc @@ -0,0 +1,33 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@typescript-eslint/ban-types": "warn", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-loss-of-precision": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-non-null-asserted-optional-chain": "off", + "@typescript-eslint/no-unnecessary-type-constraint": "warn", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-var-requires": "warn", + "no-console": "off", + "no-empty": "warn", + "no-prototype-builtins": "off", + "no-redeclare": "warn", + "no-useless-escape": "off", + "no-async-promise-executor": "off", + "prefer-const": "warn", + "array-bracket-spacing": ["error", "never"] + } +} \ No newline at end of file diff --git a/anify-backend-recode/.gitignore b/anify-backend-recode/.gitignore new file mode 100644 index 0000000..f81d56e --- /dev/null +++ b/anify-backend-recode/.gitignore @@ -0,0 +1,169 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +\*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +\*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +\*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +\*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.cache +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +.cache/ + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp +.cache + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.\* diff --git a/anify-backend-recode/.prettierignore b/anify-backend-recode/.prettierignore new file mode 100644 index 0000000..eeda442 --- /dev/null +++ b/anify-backend-recode/.prettierignore @@ -0,0 +1,12 @@ +node_modules +*.js +*.d.ts +*.md +*.json +*.lock +*.yml +*.yaml +Dockerfile +Dockerfile.* +.eslintrc +*.html \ No newline at end of file diff --git a/anify-backend-recode/.prettierrc.json b/anify-backend-recode/.prettierrc.json new file mode 100644 index 0000000..0e41e21 --- /dev/null +++ b/anify-backend-recode/.prettierrc.json @@ -0,0 +1,13 @@ +{ + "useTabs": false, + "tabWidth": 4, + "semi": true, + "singleQuote": false, + "bracketSpacing": true, + "bracketSameLine": false, + "arrowParens": "always", + "parser": "typescript", + "printWidth": 10000, + "proseWrap": "never", + "endOfLine": "lf" +} diff --git a/anify-backend-recode/README.md b/anify-backend-recode/README.md new file mode 100644 index 0000000..6077abe --- /dev/null +++ b/anify-backend-recode/README.md @@ -0,0 +1,15 @@ +# test + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +``` + +This project was created using `bun init` in bun v0.8.1. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..f96a0e996b90eba38434718ff9f7d6500ca15b86 GIT binary patch literal 36864 zcmeI%?@!Y}7zglGj&JTY*V@L1Oc5vTnUQ+Iv3tJl#mQUu{@|kwcfasUY{YSuK~- zRtV8FZA`u<k+ypL&j>$j$7erv_ToHn&G^RxJ4>PGQq@q1ye@N3B5 zp$h^KfB*y_aP0zTW}%?Z&*wgk3VL8O>RIco6YYzuHKSr0#H>8tFi6x!ZcmbUvzo*- z-kM~qw)V18+a>G9?sBj5h;>wN(!$wszbM@oQZGmE6Q|<^ePJPYwx$UD zBg-?bHuHNQ@&gdP=BrvT&+^?S^T~_t&1x^?#go&;Xs+daUN;sln``fK^>XiH;q&v+ zg0AbiudbSMn>sD3c4GrmRZUl&rf&zW)S5Ni_l&Q#X^W*g4yfZ?+~W%>0zWleSi)v1 z{A8Wm)blK-b%9DU#_u?;(`lzq*9dcncQy|Z$lzvMy< z*LHd8JRL@PH&K(3;TfD(Di+W60-JJ6bW$Cn14kP8mN;*dU z*SfvzJLd0o8(;YUtJ{%bb*pMne!+(&Ix2ru6~iA^)8TG5++l+N1Rwwb2tWV=5P$## zAOHafKp?9ElVM=^|39nCi?|>F0SG_<0uX=z1Rwwb2tWV=N&wIQkq8ig00bZa0SG_< z0uX=z1Rwx`>=14.17" + } + } + } +} diff --git a/anify-backend-recode/package.json b/anify-backend-recode/package.json new file mode 100644 index 0000000..4312bed --- /dev/null +++ b/anify-backend-recode/package.json @@ -0,0 +1,27 @@ +{ + "name": "test", + "module": "index.ts", + "type": "module", + "scripts": { + "start": "bun run dist/index.js", + "build": "bun build ./src/index.ts --outdir ./dist --target node", + "prettier": "prettier --write .", + "eslint": "eslint --ext .ts src/** --fix", + "lint": "bunx run prettier && bunx run eslint" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "latest", + "@typescript-eslint/parser": "latest", + "bun-types": "latest", + "eslint": "^8.48.0", + "prettier": "^3.0.3" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "cheerio": "^1.0.0-rc.12", + "dotenv": "^16.3.1", + "eventemitter2": "latest" + } +} diff --git a/anify-backend-recode/src/database/impl/create.ts b/anify-backend-recode/src/database/impl/create.ts new file mode 100644 index 0000000..e8cdb0e --- /dev/null +++ b/anify-backend-recode/src/database/impl/create.ts @@ -0,0 +1,124 @@ +import { db } from ".."; +import { averageMetric } from "../../helper"; +import { Type } from "../../types/enums"; +import { Anime, Manga } from "../../types/types"; + +export const create = async (data: Anime | Manga) => { + const query = ` + INSERT INTO ${data.type === "ANIME" ? "anime" : "manga"} ( + id, + slug, + coverImage, + bannerImage, + ${data.type === Type.ANIME ? "trailer," : ""} + status, + ${data.type === Type.ANIME ? "season," : ""} + title, + ${data.type === Type.ANIME ? "currentEpisode," : ""} + mappings, + synonyms, + countryOfOrigin, + description, + ${data.type === Type.ANIME ? "duration," : ""} + color, + year, + rating, + popularity, + type, + format, + relations, + ${data.type === Type.ANIME ? "totalEpisodes" : "totalChapters"}, + ${data.type === Type.MANGA ? "totalVolumes," : ""} + genres, + tags, + ${data.type === Type.ANIME ? "episodes" : "chapters"}, + averageRating, + averagePopularity, + artwork, + characters + ) VALUES ( + $id, + $slug, + $coverImage, + $bannerImage, + ${data.type === Type.ANIME ? "$trailer," : ""} + $status, + ${data.type === Type.ANIME ? "$season," : ""} + $title, + ${data.type === Type.ANIME ? "$currentEpisode," : ""} + $mappings, + $synonyms, + $countryOfOrigin, + $description, + ${data.type === Type.ANIME ? "$duration," : ""} + $color, + $year, + $rating, + $popularity, + $type, + $format, + $relations, + ${data.type === Type.ANIME ? "$totalEpisodes" : "$totalChapters"}, + ${data.type === Type.MANGA ? "$totalVolumes," : ""} + $genres, + $tags, + ${data.type === Type.ANIME ? "$episodes" : "$chapters"}, + $averageRating, + $averagePopularity, + $artwork, + $characters + ) + `; + + const params = { + $id: data.id, + $slug: data.slug, + $coverImage: data.coverImage, + $bannerImage: data.bannerImage, + $status: data.status, + $title: JSON.stringify(data.title), + $mappings: JSON.stringify(data.mappings), + $synonyms: JSON.stringify(data.synonyms), + $countryOfOrigin: data.countryOfOrigin, + $description: data.description, + $color: data.color, + $year: data.year, + $rating: JSON.stringify(data.rating), + $popularity: JSON.stringify(data.popularity), + $type: data.type, + $format: data.format, + $relations: JSON.stringify(data.relations), + $genres: JSON.stringify(data.genres), + $tags: JSON.stringify(data.tags), + $averageRating: averageMetric(data.rating), + $averagePopularity: averageMetric(data.popularity), + $artwork: JSON.stringify(data.artwork), + $characters: JSON.stringify(data.characters), + }; + + if (data.type === Type.ANIME) { + Object.assign(params, { + $trailer: (data as Anime).trailer, + $season: JSON.stringify((data as Anime).season), + $currentEpisode: (data as Anime).currentEpisode, + $duration: (data as Anime).duration, + $totalEpisodes: (data as Anime).totalEpisodes, + $episodes: JSON.stringify((data as Anime).episodes), + }); + } else { + Object.assign(params, { + $totalChapters: (data as Manga).totalChapters, + $totalVolumes: (data as Manga).totalVolumes, + $chapters: JSON.stringify((data as Manga).chapters), + }); + } + + const insert = db.prepare(query); + + return new Promise((resolve, reject) => { + db.transaction(() => { + insert.run(params); + resolve(true); + }); + }); +}; \ No newline at end of file diff --git a/anify-backend-recode/src/database/impl/get.ts b/anify-backend-recode/src/database/impl/get.ts new file mode 100644 index 0000000..9b2cb40 --- /dev/null +++ b/anify-backend-recode/src/database/impl/get.ts @@ -0,0 +1,11 @@ +import { db } from ".."; +import { Anime, Manga } from "../../types/types"; + +export const get = async (id: string): Promise => { + const anime = await db.query(`SELECT * FROM anime WHERE $id`).get({ id: id }); + if (!anime) { + return await db.query(`SELECT * FROM manga WHERE $id`).get({ id: id }) as Manga | undefined; + } else { + return anime as Anime; + } +}; \ No newline at end of file diff --git a/anify-backend-recode/src/database/impl/search.ts b/anify-backend-recode/src/database/impl/search.ts new file mode 100644 index 0000000..7901813 --- /dev/null +++ b/anify-backend-recode/src/database/impl/search.ts @@ -0,0 +1,20 @@ +import { db } from ".."; +import { Format, Type } from "../../types/enums"; + +export const search = async (query: string, type: Type, formats: Format[], page: number, perPage: number) => { + const skip = page > 0 ? perPage * (page - 1) : 0; + const where = ` + WHERE + ( + '%${query}%' IN (synonyms) + OR title->>'english' LIKE '%${query}%' + OR title->>'romaji' LIKE '%${query}%' + OR title->>'native' LIKE '%${query}%' + OR synonyms LIKE '%${query}%' + ) + ${formats?.length > 0 ? `AND "format" IN (${formats.map(f => `'${f}'`).join(', ')})` : ''} + `; + + const data = await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} ${where} ORDER BY title->>'english' ASC LIMIT ${perPage} OFFSET ${skip}`).all(); + return data; +}; \ No newline at end of file diff --git a/anify-backend-recode/src/database/impl/searchAdvanced.ts b/anify-backend-recode/src/database/impl/searchAdvanced.ts new file mode 100644 index 0000000..6671444 --- /dev/null +++ b/anify-backend-recode/src/database/impl/searchAdvanced.ts @@ -0,0 +1,64 @@ +import { db } from ".."; +import { Format, Genres, Type } from "../../types/enums"; + +export const searchAdvanced = async (query: string, type: Type, formats: Format[], page: number, perPage: number, genres: Genres[] = [], genresExcluded: Genres[] = [], year = 0, tags: string[] = [], tagsExcluded: string[] = []) => { + const skip = page > 0 ? perPage * (page - 1) : 0; + let where = ` + WHERE + ( + '%${query}%' IN (synonyms) + OR title->>'english' LIKE '%${query}%' + OR title->>'romaji' LIKE '%${query}%' + OR title->>'native' LIKE '%${query}%' + OR synonyms LIKE '%${query}%' + ) + ${formats?.length > 0 ? `AND "format" IN (${formats.map(f => `'${f}'`).join(', ')})` : ''} + `; + + if (genres && genres.length > 0) { + let genreWhere = ""; + for (let i = 0; i < genres.length; i++) { + genreWhere += `genres LIKE '%${genres[i]}%'`; + if (i < genres.length - 1) { + genreWhere += " AND "; + } + } + where += `AND (${genreWhere})`; + } + + if (genresExcluded && genresExcluded.length > 0) { + let genreWhere = ""; + for (let i = 0; i < genresExcluded.length; i++) { + genreWhere += `genres NOT LIKE '%${genresExcluded[i]}%'`; + if (i < genresExcluded.length - 1) { + genreWhere += " AND "; + } + } + where += `AND (${genreWhere})`; + } + + if (tags && tags.length > 0) { + let tagsWhere = ""; + for (let i = 0; i < tags.length; i++) { + tagsWhere += `tags LIKE '%${tags[i]}%'`; + if (i < tags.length - 1) { + tagsWhere += " AND "; + } + } + where += `AND (${tagsWhere})`; + } + + if (tags && tags.length > 0) { + let tagsWhere = ""; + for (let i = 0; i < tags.length; i++) { + tagsWhere += `tags NOT LIKE '%${tagsExcluded[i]}%'`; + if (i < tags.length - 1) { + tagsWhere += " AND "; + } + } + where += `AND (${tagsWhere})`; + } + + const data = await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} ${where} ORDER BY title->>'english' ASC LIMIT ${perPage} OFFSET ${skip}`).all(); + return data; +}; \ No newline at end of file diff --git a/anify-backend-recode/src/database/impl/seasonal.ts b/anify-backend-recode/src/database/impl/seasonal.ts new file mode 100644 index 0000000..7920bb4 --- /dev/null +++ b/anify-backend-recode/src/database/impl/seasonal.ts @@ -0,0 +1,51 @@ +import { db } from ".."; +import { Type } from "../../types/enums"; +import { Anime, Manga } from "../../types/types"; + +export const seasonal = async (trending: Anime[] | Manga[], popular: Anime[] | Manga[], top: Anime[] | Manga[], seasonal: Anime[] | Manga[]) => { + const ids = { + trending: trending.map((a) => String(a.id)), + popular: popular.map((a) => String(a.id)), + top: top.map((a) => String(a.id)), + seasonal: seasonal.map((a) => String(a.id)), + }; + + const trend = await db.query(` + SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} + WHERE id IN (${ids.trending.map((id) => `'${id}'`).join(", ")}) + ORDER BY title->>'english' ASC + `).all() as Anime[] | Manga[]; + + const pop = await db.query(` + SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} + WHERE id IN (${ids.popular.map((id) => `'${id}'`).join(", ")}) + ORDER BY title->>'english' ASC + `).all() as Anime[] | Manga[]; + + const t = await db.query(` + SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} + WHERE id IN (${ids.top.map((id) => `'${id}'`).join(", ")}) + ORDER BY title->>'english' ASC + `).all() as Anime[] | Manga[]; + + const season = await db.query(` + SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} + WHERE id IN (${ids.seasonal.map((id) => `'${id}'`).join(", ")}) + ORDER BY title->>'english' ASC + `).all() as Anime[] | Manga[]; + + trend.map((media) => { + media.characters = []; + }); + pop.map((media) => { + media.characters = []; + }); + t.map((media) => { + media.characters = []; + }); + season.map((media) => { + media.characters = []; + }); + + return { trending: trend, popular: pop, top: t, seasonal: season }; +}; \ No newline at end of file diff --git a/anify-backend-recode/src/database/index.ts b/anify-backend-recode/src/database/index.ts new file mode 100644 index 0000000..ddafbfb --- /dev/null +++ b/anify-backend-recode/src/database/index.ts @@ -0,0 +1,93 @@ +import { Database } from "bun:sqlite"; + +export const db = new Database("db.sqlite"); + +export const init = async() => { + const anime = ` + CREATE TABLE IF NOT EXISTS anime ( + id TEXT PRIMARY KEY, + slug TEXT, + coverImage TEXT, + bannerImage TEXT, + trailer TEXT, + status TEXT, + season TEXT DEFAULT 'UNKNOWN', + title JSON, + currentEpisode INTEGER, + mappings JSON DEFAULT '{}', + synonyms TEXT, + countryOfOrigin TEXT, + description TEXT, + duration INTEGER, + color TEXT, + year INTEGER, + rating JSON, + popularity JSON, + type TEXT, + format TEXT DEFAULT 'UNKNOWN', + relations JSON, + totalEpisodes REAL, + genres TEXT, + tags TEXT, + episodes JSON DEFAULT '{"latest": {"updatedAt": 0, "latestEpisode": 0, "latestTitle": ""}, "data": []}', + averageRating REAL, + averagePopularity REAL, + artwork JSON DEFAULT '[]', + characters JSON DEFAULT '[]' + ); + `; + + const manga = ` + CREATE TABLE IF NOT EXISTS manga ( + id TEXT PRIMARY KEY, + slug TEXT, + coverImage TEXT, + bannerImage TEXT, + status TEXT, + title JSON, + mappings JSON DEFAULT '{}', + synonyms TEXT, + countryOfOrigin TEXT, + description TEXT, + duration INTEGER, + color TEXT, + year INTEGER, + rating JSON, + popularity JSON, + type TEXT, + format TEXT DEFAULT 'UNKNOWN', + relations JSON, + totalChapters REAL, + totalVolumes REAL, + genres TEXT, + tags TEXT, + chapters JSON DEFAULT '{"latest": {"updatedAt": 0, "latestChapter": 0, "latestTitle": ""}, "data": []}', + averageRating REAL, + averagePopularity REAL, + artwork JSON DEFAULT '[]', + characters JSON DEFAULT '[]' + ); + `; + + const skipTimes = ` + CREATE TABLE IF NOT EXISTS skipTimes ( + id TEXT PRIMARY KEY, + episodes JSON DEFAULT '{}' + ); + `; + + const apiKey = ` + CREATE TABLE IF NOT EXISTS apiKey ( + id TEXT PRIMARY KEY, + key TEXT, + requestCount INTEGER DEFAULT 0, + createdAt INTEGER DEFAULT 0, + updatedAt INTEGER DEFAULT 0 + ); + `; + + await db.query(anime).run(); + await db.query(manga).run(); + await db.query(skipTimes).run(); + await db.query(apiKey).run(); +}; \ No newline at end of file diff --git a/anify-backend-recode/src/helper/index.ts b/anify-backend-recode/src/helper/index.ts new file mode 100644 index 0000000..84ba278 --- /dev/null +++ b/anify-backend-recode/src/helper/index.ts @@ -0,0 +1,23 @@ +export function setIntervalImmediately(func: () => Promise, interval: number) { + func(); + return setInterval(async () => { + try { + await func(); + } catch (e) { + console.error("Error occurred while trying to execute the interval function: ", e); + } + }, interval); +} + +export const averageMetric = (object: any) => { + let average = 0, + validCount = 0; + for (const [_, v] of Object.entries(object)) { + if (v && typeof v === "number") { + average += v; + validCount++; + } + } + + return validCount === 0 ? 0 : Number.parseFloat((average / validCount).toFixed(2)); +}; \ No newline at end of file diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts new file mode 100644 index 0000000..8a12299 --- /dev/null +++ b/anify-backend-recode/src/index.ts @@ -0,0 +1,10 @@ +import dotenv from "dotenv"; +dotenv.config(); + +import { search } from "./database/impl/search"; +import { Type } from "./types/enums"; +import { init } from "./database"; + +init().then((data) => { + search("Mushoku Tensei", Type.ANIME, [], 0, 10).then(console.log) +}) \ No newline at end of file diff --git a/anify-backend-recode/src/lib/event.ts b/anify-backend-recode/src/lib/event.ts new file mode 100644 index 0000000..f2c61a2 --- /dev/null +++ b/anify-backend-recode/src/lib/event.ts @@ -0,0 +1,14 @@ +import EventEmitter2 from "eventemitter2"; + +export enum Events { + COMPLETED_MAPPING_LOAD = "mapping.load.completed", + COMPLETED_SKIPTIMES_LOAD = "skiptimes.load.completed", + COMPLETED_SEARCH_LOAD = "search.load.completed", + COMPLETED_SEASONAL_LOAD = "seasonal.load.completed", + COMPLETED_ENTRY_CREATION = "entry.creation.completed", + COMPLETED_PAGE_UPLOAD = "page.upload.completed", +} + +const emitter = new EventEmitter2({}); + +export default emitter; diff --git a/anify-backend-recode/src/lib/executor.ts b/anify-backend-recode/src/lib/executor.ts new file mode 100644 index 0000000..428102e --- /dev/null +++ b/anify-backend-recode/src/lib/executor.ts @@ -0,0 +1,163 @@ +import { setIntervalImmediately } from "../helper"; + +export default class QueueExecutor { + id: string; + private intervalId: NodeJS.Timer | undefined; + private intervalN: number | undefined; + private executorFunc: ((args: T, meta: any) => Promise) | undefined; + private callbackFunc: ((args: T) => Promise | void) | undefined; + private errorFunc: ((error: Error, args: T) => Promise | void) | undefined; + private runConditionFunc: (() => boolean) | undefined; + + private queue: Set = new Set(); + private metaMap: Map = new Map(); + private paused = false; + private activeBySwitch = false; + private active = true; + private isExecuteAfterDone = false; + private running = false; + private isSelfRunning = false; + + constructor(id: string) { + this.id = id; + } + + selfRunning(): QueueExecutor { + this.isSelfRunning = true; + + return this; + } + + interval(n: number): QueueExecutor { + this.intervalN = n; + + return this; + } + + executor(func: (args: T, meta: any) => Promise): QueueExecutor { + this.executorFunc = func; + + return this; + } + + callback(func: (args: T) => Promise | void): QueueExecutor { + this.callbackFunc = func; + + return this; + } + + error(func: (error: Error, args: T) => Promise | void): QueueExecutor { + this.errorFunc = func; + + return this; + } + + add(arg: T, meta: any = undefined) { + this.queue.add(arg); + if (meta) { + this.metaMap.set(arg, meta); + } + } + + executeAfterDone(): QueueExecutor { + this.isExecuteAfterDone = true; + + return this; + } + + runCondition(func: () => boolean): QueueExecutor { + this.runConditionFunc = func; + + return this; + } + + deactivate() { + this.active = false; + + return this; + } + + activate() { + this.active = true; + + return this; + } + + activateBySwitch() { + this.activeBySwitch = true; + + return this; + } + + start() { + if (!this.intervalN || !this.executorFunc) throw new Error("Both interval and executor function need to be supplied"); + + this.intervalId = setIntervalImmediately(async () => { + if (this.paused || (this.queue.size <= 0 && !this.activeBySwitch && !this.isSelfRunning)) return; + if (this.runConditionFunc && !this.runConditionFunc()) return; + if (this.isExecuteAfterDone && this.running) return; + + if (this.activeBySwitch) { + if (this.active) { + this.running = true; + if (this.executorFunc) + this.executorFunc(true as any, undefined) + .then((_) => { + if (this.callbackFunc) this.callbackFunc(true as any); + this.running = false; + }) + .catch((err) => { + if (this.errorFunc) this.errorFunc(err, true as any); + this.running = false; + }); + } + } else { + if (this.isSelfRunning) { + if (this.executorFunc) + this.executorFunc(undefined as T, undefined) + .then((_) => { + if (this.callbackFunc) this.callbackFunc(undefined as T); + this.running = false; + }) + .catch((err) => { + if (this.errorFunc) this.errorFunc(err, undefined as T); + this.running = false; + }); + } else { + const value = this.queue.values().next().value; + if (value) { + const meta = this.metaMap.get(value); + this.queue.delete(value); + this.metaMap.delete(value); + this.running = true; + if (this.executorFunc) + this.executorFunc(value, meta) + .then((_) => { + if (this.callbackFunc) this.callbackFunc(value); + this.running = false; + }) + .catch((err) => { + if (this.errorFunc) this.errorFunc(err, value); + this.running = false; + }); + } + } + } + }, this.intervalN); + + return this; + } + + pause() { + this.paused = true; + } + + unpause() { + this.paused = false; + } + + destroy() { + this.queue.clear(); + clearInterval(this.intervalId); + } +} diff --git a/anify-backend-recode/src/lib/impl/entry.ts b/anify-backend-recode/src/lib/impl/entry.ts new file mode 100644 index 0000000..c34c990 --- /dev/null +++ b/anify-backend-recode/src/lib/impl/entry.ts @@ -0,0 +1,28 @@ +import { create } from "../../database/impl/create"; +import { get } from "../../database/impl/get"; +import { Type } from "../../types/enums"; +import { Anime, Manga } from "../../types/types"; +import emitter, { Events } from "../event"; + +export const createEntry = async (data: { toInsert: Anime | Manga; type: Type }) => { + const existing = await get(String(data.toInsert.id)); + + if (existing) { + await emitter.emitAsync(Events.COMPLETED_ENTRY_CREATION, data.toInsert); + return existing; + } + + if (data.type === Type.ANIME) { + if (Array.isArray((data.toInsert as any).season)) { + (data.toInsert as any).season = (data.toInsert as any).season[0]; + } + } + + (data.toInsert as any).id = String(data.toInsert.id); + + await create(data.toInsert); + + await emitter.emitAsync(Events.COMPLETED_ENTRY_CREATION, data.toInsert); + + return data.toInsert; +}; \ No newline at end of file diff --git a/anify-backend-recode/src/lib/index.ts b/anify-backend-recode/src/lib/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/anify-backend-recode/src/types/enums.ts b/anify-backend-recode/src/types/enums.ts new file mode 100644 index 0000000..8527ea8 --- /dev/null +++ b/anify-backend-recode/src/types/enums.ts @@ -0,0 +1,130 @@ +export const enum Type { + ANIME = "ANIME", + MANGA = "MANGA", +} + +export const enum ProviderType { + ANIME = "ANIME", + MANGA = "MANGA", + META = "META", + INFORMATION = "INFORMATION", +} + +export const enum Format { + TV = "TV", + TV_SHORT = "TV_SHORT", + MOVIE = "MOVIE", + SPECIAL = "SPECIAL", + OVA = "OVA", + ONA = "ONA", + MUSIC = "MUSIC", + MANGA = "MANGA", + NOVEL = "NOVEL", + ONE_SHOT = "ONE_SHOT", + UNKNOWN = "UNKNOWN", +} + +export const enum Season { + WINTER = "WINTER", + SPRING = "SPRING", + SUMMER = "SUMMER", + FALL = "FALL", + UNKNOWN = "UNKNOWN", +} + +export const enum MediaStatus { + FINISHED = "FINISHED", + RELEASING = "RELEASING", + NOT_YET_RELEASED = "NOT_YET_RELEASED", + CANCELLED = "CANCELLED", + HIATUS = "HIATUS", +} + +export const enum Genres { + ACTION = "Action", + ADVENTURE = "Adventure", + ANIME_INFLUENCED = "Anime Influenced", + AVANT_GARDE = "Avant Garde", + AWARD_WINNING = "Award Winning", + BOYS_LOVE = "Boys Love", + CARS = "Cards", + COMEDY = "Comedy", + DEMENTIA = "Dementia", + DEMONS = "Demons", + DOUJINSHI = "Doujinshi", + DRAMA = "Drama", + ECCHI = "Ecchi", + EROTICA = "Erotica", + FAMILY = "Family", + FANTASY = "Fantasy", + FOOD = "Food", + FRIENDSHIP = "Friendship", + GAME = "Game", + GENDER_BENDER = "Gender Bender", + GIRLS_LOVE = "Girls Love", + GORE = "Gore", + GOURMET = "Gourmet", + HAREM = "Harem", + HENTAI = "Hentai", + HISTORICAL = "Historical", + HORROR = "Horror", + ISEKAI = "Isekai", + KIDS = "Kids", + MAGIC = "Magic", + MAHOU_SHOUJO = "Mahou Shoujo", + MARTIAL_ARTS = "Martial Arts", + MECHA = "Mecha", + MEDICAL = "Medical", + MILITARY = "Military", + MUSIC = "Music", + MYSTERY = "Mystery", + PARODY = "Parody", + POLICE = "Police", + POLITICAL = "Political", + PSYCHOLOGICAL = "Psychological", + RACING = "Racing", + ROMANCE = "Romance", + SAMURAI = "Samurai", + SCHOOL = "School", + SCI_FI = "Sci-Fi", + SHOUJO_AI = "Shoujo Ai", + SHOUNEN_AI = "Shounen Ai", + SLICE_OF_LIFE = "Slice of Life", + SPACE = "Space", + SPORTS = "Sports", + SUPER_POWER = "Super Power", + SUPERNATURAL = "Supernatural", + SUSPENCE = "Suspence", + THRILLER = "Thriller", + VAMPIRE = "Vampire", + WORKPLACE = "Workplace", + YAOI = "Yaoi", + YURI = "Yuri", + ZOMBIES = "Zombies", +} + +export const enum SubType { + DUB = "dub", + SUB = "sub", +} + +export const enum StreamingServers { + AsianLoad = "asianload", + GogoCDN = "gogocdn", + StreamSB = "streamsb", + MixDrop = "mixdrop", + UpCloud = "upcloud", + VidCloud = "vidcloud", + StreamTape = "streamtape", + VizCloud = "vizcloud", + MyCloud = "mycloud", + Filemoon = "filemoon", + VidStreaming = "vidstreaming", + AllAnime = "allanime", + FPlayer = "fplayer", + Kwik = "kwik", + DuckStream = "duckstream", + DuckStreamV2 = "duckstreamv2", + BirdStream = "birdstream", + AnimeFlix = "animeflix", +} \ No newline at end of file diff --git a/anify-backend-recode/src/types/types.ts b/anify-backend-recode/src/types/types.ts new file mode 100644 index 0000000..a99c698 --- /dev/null +++ b/anify-backend-recode/src/types/types.ts @@ -0,0 +1,192 @@ +import { Format, Genres, MediaStatus, ProviderType, Season, SubType, Type } from "./enums"; + +export type Anime = { + id: string; + slug: string; + coverImage: string | null; + bannerImage: string | null; + trailer: string | null; + status: MediaStatus | null; + season: Season; + title: { + romaji: string | null; + english: string | null; + native: string | null; + }; + currentEpisode: number | null; + mappings: { id: string; providerId: string; similarity: number; providerType: ProviderType | null }[]; + synonyms: string[]; + countryOfOrigin: string | null; + description: string | null; + duration: number | null; + color: string | null; + year: number | null; + rating: { + anilist: number; + mal: number; + kitsu: number; + }; + popularity: { + anilist: number; + mal: number; + kitsu: number; + }; + averageRating?: number; + averagePopularity?: number; + type: Type; + genres: Genres[]; + format: Format; + relations: Relations[]; + totalEpisodes?: number; + episodes: { + latest: { + updatedAt: number; + latestEpisode: number; + latestTitle: string; + }; + data: EpisodeData[]; + }; + tags: string[]; + artwork: Artwork[]; + characters: Character[]; +}; + +export type Manga = { + id: string; + slug: string; + coverImage: string | null; + bannerImage: string | null; + status: MediaStatus | null; + title: { + romaji: string | null; + english: string | null; + native: string | null; + }; + mappings: { id: string; providerId: string; similarity: number; providerType: ProviderType | null }[]; + synonyms: string[]; + countryOfOrigin: string | null; + description: string | null; + totalVolumes: number | null; + color: string | null; + year: number | null; + rating: { + anilist: number; + mal: number; + kitsu: number; + }; + popularity: { + anilist: number; + mal: number; + kitsu: number; + }; + averageRating?: number; + averagePopularity?: number; + genres: Genres[]; + type: Type; + format: Format; + relations: Relations[]; + totalChapters: number | null; + chapters: { + latest: { + updatedAt: number; + latestChapter: number; + latestTitle: string; + }; + data: ChapterData[]; + }; + tags: string[]; + artwork: Artwork[]; + characters: Character[]; +}; + +export interface Character { + name: string; + image: string; + voiceActor: { + name: string; + image: string; + }; +} + +export type Relations = { + id: string; + type: Type; + title: { + english: string | null; + romaji: string | null; + native: string | null; + }; + format: Format; + relationType: string; +}; + +export type Artwork = { + type: "banner" | "poster" | "clear_logo" | "top_banner" | "icon" | "clear_art"; + img: string; + providerId: string; +}; + +export type EpisodeData = { + providerId: string; + episodes: Episode[]; +}; + +export type Episode = { + id: string; + title: string; + number: number; + isFiller: boolean; + img: string | null; + hasDub: boolean; + updatedAt?: number; +}; + +export type ChapterData = { + providerId: string; + chapters: Chapter[]; +}; + +export type Chapter = { + id: string; + title: string; + number: number; + updatedAt?: number; + mixdrop?: string; +}; + +export type Page = { + url: string; + index: number; + headers: { [key: string]: string }; +}; + +export type Source = { + sources: { url: string; quality: string }[]; + subtitles: { url: string; lang: string; label: string }[]; + audio: { url: string; name: string; language: string }[]; + intro: { + start: number; + end: number; + }; + outro: { + start: number; + end: number; + }; + headers: Record; +}; + +export type Server = { + name: string; + url: string; + type?: SubType; +}; + +export type Result = { + id: string; + title: string; + altTitles: string[]; + year: number; + format: Format; + img: string | null; + providerId: string; +}; \ No newline at end of file diff --git a/anify-backend-recode/tsconfig.json b/anify-backend-recode/tsconfig.json new file mode 100644 index 0000000..388a057 --- /dev/null +++ b/anify-backend-recode/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "jsx": "preserve", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [ + "bun-types" // add Bun global + ] + } +} diff --git a/anify-backend/package-lock.json b/anify-backend/package-lock.json index 23c4341..36309bd 100644 --- a/anify-backend/package-lock.json +++ b/anify-backend/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@extractus/article-extractor": "^7.2.16", + "@extractus/article-extractor": "^8.0.2", "@prisma/client": "^4.15.0", "@types/probe-image-size": "^7.2.0", "bun": "^0.8.1", @@ -40,10 +40,8 @@ "prisma-json-types-generator": "^2.4.0", "rimraf": "^5.0.1", "ts-node": "^10.9.1", - "tsconfig-paths": "^4.2.0", - "tscpaths": "^0.0.9", "tslib": "^2.5.3", - "typescript": "^4.9.5" + "typescript": "^5.2.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -179,19 +177,18 @@ } }, "node_modules/@extractus/article-extractor": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@extractus/article-extractor/-/article-extractor-7.2.16.tgz", - "integrity": "sha512-LV55IG1QOMTDzbb4Cb6TQ8LMoh+smtr6pIAEA7IWTUw8VbSQZtRPr0Go6akJSb/XaaKv4KrtsxNyrhyAjtWrcA==", - "license": "MIT", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@extractus/article-extractor/-/article-extractor-8.0.2.tgz", + "integrity": "sha512-z1Kde0H6U4y8v8VbQaxaE4RliMOrVIS/KUmoRmQ7cJn9N2OPFT5K5pucRml3DCWjyEFftLmVQzJDdo3HLLMCzQ==", "dependencies": { "@mozilla/readability": "^0.4.4", "bellajs": "^11.1.2", - "cross-fetch": "^3.1.6", - "linkedom": "^0.14.26", - "sanitize-html": "2.10.0" + "cross-fetch": "^4.0.0", + "linkedom": "^0.15.1", + "sanitize-html": "2.11.0" }, "engines": { - "node": ">= 14" + "node": ">= 15" } }, "node_modules/@humanwhocodes/config-array": { @@ -349,20 +346,6 @@ "node": ">=14.0.0" } }, - "node_modules/@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -596,17 +579,6 @@ "@types/ms": "*" } }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -614,13 +586,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/ms": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", @@ -976,36 +941,6 @@ "dev": true, "license": "MIT" }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-buffer-byte-length": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", @@ -1025,68 +960,12 @@ "license": "MIT", "peer": true }, - "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -1104,38 +983,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1245,27 +1092,6 @@ "node": ">= 0.8" } }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -1279,13 +1105,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true, - "license": "MIT" - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1349,22 +1168,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -1394,20 +1197,6 @@ "node": ">=0.10.0" } }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1447,20 +1236,6 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true, - "license": "MIT" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1497,16 +1272,6 @@ "license": "MIT", "peer": true }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/copyfiles": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", @@ -1555,12 +1320,11 @@ "license": "MIT" }, "node_modules/cross-fetch": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", - "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", - "license": "MIT", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dependencies": { - "node-fetch": "^2.6.11" + "node-fetch": "^2.6.12" } }, "node_modules/cross-spawn": { @@ -1614,8 +1378,7 @@ "node_modules/cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", - "license": "MIT" + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" }, "node_modules/debug": { "version": "4.3.4", @@ -1634,16 +1397,6 @@ } } }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/deep-equal": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz", @@ -1686,7 +1439,6 @@ "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==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1706,96 +1458,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1850,19 +1512,6 @@ "node": ">=0.3.1" } }, - "node_modules/dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2026,6 +1675,17 @@ "license": "MIT", "peer": true }, + "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint": { "version": "8.45.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", @@ -2108,17 +1768,6 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, - "node_modules/eslint/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/eslint-scope": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", @@ -2303,48 +1952,12 @@ "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", "license": "MIT" }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "license": "MIT", - "peer": true, + "peer": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -2463,284 +2076,12 @@ "node": ">= 0.8" } }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "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==", "license": "MIT" }, - "node_modules/fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/fast-glob/node_modules/@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-glob/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/braces/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/fill-range/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2876,16 +2217,6 @@ "is-callable": "^1.1.3" } }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/foreground-child": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", @@ -2939,19 +2270,6 @@ "node": ">= 0.6" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "license": "MIT", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -3006,16 +2324,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", @@ -3046,13 +2354,6 @@ "node": ">= 6" } }, - "node_modules/glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", - "dev": true, - "license": "BSD" - }, "node_modules/globals": { "version": "13.20.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", @@ -3259,53 +2560,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/html-escaper": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", - "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", - "license": "MIT" + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" }, "node_modules/htmlparser2": { "version": "8.0.2", @@ -3355,16 +2613,6 @@ "node": ">=0.10.0" } }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -3462,29 +2710,6 @@ "node": ">= 0.10" } }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -3539,13 +2764,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "license": "MIT" - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -3557,76 +2775,18 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "license": "MIT", + "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==", "dependencies": { - "kind-of": "^6.0.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-extglob": { @@ -3658,19 +2818,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.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", @@ -3693,19 +2840,6 @@ "node": ">=8" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -3802,16 +2936,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -3825,16 +2949,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/jackspeak": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", @@ -3866,32 +2980,6 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "license": "MIT" }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -3922,10 +3010,9 @@ } }, "node_modules/linkedom": { - "version": "0.14.26", - "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.14.26.tgz", - "integrity": "sha512-mK6TrydfFA7phrnp+1j57ycBwFI5bGSW6YXlw9acHoqF+mP/y+FooEYYyniOt5Ot57FSKB3iwmnuQ1UUyNLm5A==", - "license": "ISC", + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.15.3.tgz", + "integrity": "sha512-p+lBSEWzawF3Gy7+nw+5+u+iDthsfZZVd9lwiO96Ihj7Zd8he5BD1Wzdc9Z4GqtU6lKvxhye4W4Zr20uOAGe4A==", "dependencies": { "css-select": "^5.1.0", "cssom": "^0.5.0", @@ -3971,29 +3058,6 @@ "dev": true, "license": "ISC" }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -4091,16 +3155,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minipass": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", @@ -4111,33 +3165,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4154,7 +3181,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -4162,80 +3188,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4284,10 +3236,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", - "license": "MIT", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -4326,21 +3277,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -4373,19 +3309,6 @@ "node": ">= 0.4" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.assign": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", @@ -4403,19 +3326,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -4489,8 +3399,7 @@ "node_modules/parse-srcset": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", - "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==", - "license": "MIT" + "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" }, "node_modules/parse5": { "version": "7.1.2", @@ -4527,23 +3436,6 @@ "node": ">= 0.8" } }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true, - "license": "MIT" - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4605,29 +3497,6 @@ "license": "MIT", "peer": true }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-type/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/pdfkit": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/pdfkit/-/pdfkit-0.13.0.tgz", @@ -4642,8 +3511,7 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "license": "ISC" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -4658,35 +3526,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/png-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz", "integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==" }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", "funding": [ { "type": "opencollective", @@ -4701,7 +3549,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -4910,81 +3757,20 @@ "node": ">=4" } }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "license": "MIT", + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/require-directory": { @@ -4997,28 +3783,11 @@ "node": ">=0.10.0" } }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "dev": true, - "license": "MIT" - }, "node_modules/restructure": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/restructure/-/restructure-2.0.1.tgz", "integrity": "sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg==" }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -5141,16 +3910,6 @@ "license": "MIT", "peer": true }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ret": "~0.1.10" - } - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -5158,10 +3917,9 @@ "license": "MIT" }, "node_modules/sanitize-html": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.10.0.tgz", - "integrity": "sha512-JqdovUd81dG4k87vZt6uA6YhDfWkUGruUu/aPmXLxXi45gZExnt9Bnw/qeQU8oGf82vPyaE0vO4aH0PbobB9JQ==", - "license": "MIT", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.11.0.tgz", + "integrity": "sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==", "dependencies": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", @@ -5171,23 +3929,10 @@ "postcss": "^8.3.11" } }, - "node_modules/sanitize-html/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==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/sanitize-html/node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5277,22 +4022,6 @@ "node": ">= 0.8.0" } }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -5345,160 +4074,10 @@ "node": ">=8" } }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "license": "MIT", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true, - "license": "MIT" - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, "engines": { "node": ">=0.10.0" } @@ -5509,20 +4088,6 @@ "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", "license": "MIT" }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -5649,16 +4214,6 @@ "node": ">=8" } }, - "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, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -5738,35 +4293,6 @@ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5790,47 +4316,6 @@ "node": ">=0.12.0" } }, - "node_modules/to-regex/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -5844,8 +4329,7 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/ts-node": { "version": "10.9.1", @@ -5891,65 +4375,6 @@ } } }, - "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, - "license": "MIT", - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tscpaths": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/tscpaths/-/tscpaths-0.0.9.tgz", - "integrity": "sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^2.20.0", - "globby": "^9.2.0" - }, - "bin": { - "tscpaths": "cjs/index.js" - } - }, - "node_modules/tscpaths/node_modules/globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tscpaths/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/tslib": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", @@ -6005,23 +4430,22 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/uhyphen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz", - "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==", - "license": "ISC" + "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==" }, "node_modules/unicode-properties": { "version": "1.4.1", @@ -6041,22 +4465,6 @@ "tiny-inflate": "^1.0.0" } }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -6067,58 +4475,6 @@ "node": ">= 0.8" } }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/untildify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", @@ -6138,23 +4494,6 @@ "punycode": "^2.1.0" } }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -6192,14 +4531,12 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" diff --git a/anify-backend/package.json b/anify-backend/package.json index 957d2ec..060611e 100644 --- a/anify-backend/package.json +++ b/anify-backend/package.json @@ -12,7 +12,7 @@ "rimraf": "^5.0.1", "ts-node": "^10.9.1", "tslib": "^2.5.3", - "typescript": "^4.9.5" + "typescript": "^5.2.2" }, "name": "anify-backend", "description": "Anify backend", @@ -22,7 +22,7 @@ "scripts": { "dev": "bun run src/index.ts", "crawl": "bun run src/crawl.ts", - "start": "bun run dist/index.js", + "start": "bun run dist/index.js/index.js", "copy-files": "copyfiles -u 1 src/**/*.json dist/", "build": "npm run check:env && npm run build:db && npm run lint && npm run build:bun", "rebuild": "npm run clean && npm run build:ts", diff --git a/anify-backend/src/mapping/impl/anime/nineanime.ts b/anify-backend/src/mapping/impl/anime/nineanime.ts index bd1a4fe..ce19b09 100644 --- a/anify-backend/src/mapping/impl/anime/nineanime.ts +++ b/anify-backend/src/mapping/impl/anime/nineanime.ts @@ -11,7 +11,6 @@ export default class NineAnime extends AnimeProvider { override url = "https://aniwave.to"; override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; - private userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42"; private resolver: string | undefined = env.NINEANIME_RESOLVER; private resolverKey: string | undefined = env.NINEANIME_KEY || `9anime`; @@ -346,4 +345,4 @@ export default class NineAnime extends AnimeProvider { type VRF = { url: string; vrfQuery: string; -}; +}; \ No newline at end of file diff --git a/anify-backend/tsconfig.json b/anify-backend/tsconfig.json index 2ac83cd..496bcec 100644 --- a/anify-backend/tsconfig.json +++ b/anify-backend/tsconfig.json @@ -6,6 +6,7 @@ // enable latest features "lib": ["esnext"], "module": "esnext", + "allowImportingTsExtensions": true, "target": "esnext", // if TS 5.x+ diff --git a/anify-backend/yarn.lock b/anify-backend/yarn.lock index b65cba3..c84431e 100644 --- a/anify-backend/yarn.lock +++ b/anify-backend/yarn.lock @@ -46,16 +46,16 @@ resolved "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz" integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== -"@extractus/article-extractor@^7.2.16": - version "7.2.16" - resolved "https://registry.npmjs.org/@extractus/article-extractor/-/article-extractor-7.2.16.tgz" - integrity sha512-LV55IG1QOMTDzbb4Cb6TQ8LMoh+smtr6pIAEA7IWTUw8VbSQZtRPr0Go6akJSb/XaaKv4KrtsxNyrhyAjtWrcA== +"@extractus/article-extractor@^8.0.2": + version "8.0.2" + resolved "https://registry.npmjs.org/@extractus/article-extractor/-/article-extractor-8.0.2.tgz" + integrity sha512-z1Kde0H6U4y8v8VbQaxaE4RliMOrVIS/KUmoRmQ7cJn9N2OPFT5K5pucRml3DCWjyEFftLmVQzJDdo3HLLMCzQ== dependencies: "@mozilla/readability" "^0.4.4" bellajs "^11.1.2" - cross-fetch "^3.1.6" - linkedom "^0.14.26" - sanitize-html "2.10.0" + cross-fetch "^4.0.0" + linkedom "^0.15.1" + sanitize-html "2.11.0" "@humanwhocodes/config-array@^0.11.10": version "0.11.10" @@ -116,14 +116,6 @@ resolved "https://registry.npmjs.org/@mozilla/readability/-/readability-0.4.4.tgz" integrity sha512-MCgZyANpJ6msfvVMi6+A0UAsvZj//4OHREYUB9f2087uXHVoU+H+SWhuihvb1beKpM323bReQPRio0WNk2+V6g== -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -132,11 +124,6 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - "@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" @@ -237,24 +224,11 @@ dependencies: "@types/ms" "*" -"@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/minimatch@*": - version "5.1.2" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - "@types/ms@*": version "0.7.31" resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" @@ -441,21 +415,6 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" - integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" - integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== - array-buffer-byte-length@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" @@ -469,43 +428,16 @@ array-flatten@1.1.1: resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== -array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" - integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== - dependencies: - array-uniq "^1.0.1" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" - integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" - integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - available-typed-arrays@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" @@ -516,19 +448,6 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base@^0.11.1: - version "0.11.2" - resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - base64-js@^1.1.2, base64-js@^1.3.0: version "1.5.1" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" @@ -582,22 +501,6 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - braces@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -634,21 +537,6 @@ bytes@3.1.2: resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" @@ -657,11 +545,6 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -call-me-maybe@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz" - integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== - callsites@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" @@ -700,16 +583,6 @@ cheerio@1.0.0-rc.12: parse5 "^7.0.0" parse5-htmlparser2-tree-adapter "^7.0.0" -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - cliui@^7.0.2: version "7.0.4" resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" @@ -729,14 +602,6 @@ cluster-key-slot@^1.1.0: resolved "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz" integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" - integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - color-convert@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" @@ -761,16 +626,6 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" @@ -798,11 +653,6 @@ cookie@0.5.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" - integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== - copyfiles@^2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz" @@ -826,12 +676,12 @@ create-require@^1.1.0: resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-fetch@^3.1.6: - version "3.1.6" - resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz" - integrity sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g== +cross-fetch@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== dependencies: - node-fetch "^2.6.11" + node-fetch "^2.6.12" cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@7.0.3: version "7.0.3" @@ -868,20 +718,6 @@ cssom@^0.5.0: resolved "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz" integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== -debug@^2.2.0: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^2.3.3: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - debug@^3.2.6: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" @@ -910,11 +746,6 @@ debug@2.6.9: dependencies: ms "2.0.0" -decode-uri-component@^0.2.0: - version "0.2.2" - resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" - integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== - deep-equal@^2.0.5: version "2.2.2" resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz" @@ -957,28 +788,6 @@ define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" - integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" - integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" @@ -1009,13 +818,6 @@ diff@^4.0.1: resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz" - integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== - dependencies: - path-type "^3.0.0" - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" @@ -1242,19 +1044,6 @@ eventemitter2@^6.4.9: resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz" integrity sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg== -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" - integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - express-rate-limit@^6: version "6.7.0" resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.7.0.tgz" @@ -1297,60 +1086,11 @@ express-rate-limit@^6: utils-merge "1.0.1" vary "~1.1.2" -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 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== -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - fast-glob@^3.2.9: version "3.2.12" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" @@ -1386,16 +1126,6 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" - integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -1459,11 +1189,6 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" - integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== - foreground-child@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" @@ -1486,13 +1211,6 @@ forwarded@0.2.0: resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" - integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== - dependencies: - map-cache "^0.2.2" - fresh@0.5.2: version "0.5.2" resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" @@ -1528,19 +1246,6 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ has-proto "^1.0.1" has-symbols "^1.0.3" -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" - integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz" - integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" @@ -1555,11 +1260,6 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz" - integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== - glob@^10.2.5: version "10.2.6" resolved "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz" @@ -1602,20 +1302,6 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - gopd@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" @@ -1667,37 +1353,6 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" - integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" - integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" - integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" - integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - has@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" @@ -1738,11 +1393,6 @@ iconv-lite@^0.4.4, iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ignore@^4.0.3: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - ignore@^5.2.0: version "5.2.4" resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" @@ -1803,20 +1453,6 @@ ipaddr.js@1.9.1: resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" - integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" @@ -1849,30 +1485,11 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - is-callable@^1.1.3: version "1.2.7" resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" @@ -1880,37 +1497,7 @@ is-date-object@^1.0.5: dependencies: has-tostringtag "^1.0.0" -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== @@ -1920,13 +1507,6 @@ is-fullwidth-code-point@^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== -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz" - integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== - dependencies: - is-extglob "^2.1.0" - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" @@ -1946,13 +1526,6 @@ is-number-object@^1.0.4: dependencies: has-tostringtag "^1.0.0" -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" - integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== - dependencies: - kind-of "^3.0.2" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" @@ -1963,13 +1536,6 @@ is-path-inside@^3.0.3: resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - is-plain-object@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz" @@ -2029,17 +1595,12 @@ is-weakset@^2.0.1: call-bind "^1.0.2" get-intrinsic "^1.1.1" -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - isarray@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isarray@~1.0.0, isarray@1.0.0: +isarray@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== @@ -2054,18 +1615,6 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" - integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - jackspeak@^2.0.3: version "2.2.1" resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz" @@ -2092,40 +1641,6 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json5@^2.2.2: - version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" - integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0: - version "6.0.3" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - levn@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" @@ -2142,10 +1657,10 @@ linebreak@^1.0.2: base64-js "0.0.8" unicode-trie "^2.0.0" -linkedom@^0.14.26: - version "0.14.26" - resolved "https://registry.npmjs.org/linkedom/-/linkedom-0.14.26.tgz" - integrity sha512-mK6TrydfFA7phrnp+1j57ycBwFI5bGSW6YXlw9acHoqF+mP/y+FooEYYyniOt5Ot57FSKB3iwmnuQ1UUyNLm5A== +linkedom@^0.15.1: + version "0.15.3" + resolved "https://registry.npmjs.org/linkedom/-/linkedom-0.15.3.tgz" + integrity sha512-p+lBSEWzawF3Gy7+nw+5+u+iDthsfZZVd9lwiO96Ihj7Zd8he5BD1Wzdc9Z4GqtU6lKvxhye4W4Zr20uOAGe4A== dependencies: css-select "^5.1.0" cssom "^0.5.0" @@ -2192,18 +1707,6 @@ make-error@^1.1.1: resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" - integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== - dependencies: - object-visit "^1.0.0" - media-typer@0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" @@ -2214,7 +1717,7 @@ merge-descriptors@1.0.1: resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: +merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -2224,25 +1727,6 @@ methods@~1.1.2: resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== -micromatch@^3.1.10: - version "3.1.10" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - micromatch@^4.0.4: version "4.0.5" resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" @@ -2282,24 +1766,11 @@ minimatch@^9.0.1: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - "minipass@^5.0.0 || ^6.0.2": version "6.0.2" resolved "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz" integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" @@ -2325,23 +1796,6 @@ nanoid@^3.3.6: resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - natural-compare-lite@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" @@ -2366,10 +1820,10 @@ negotiator@0.6.3: resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -node-fetch@^2.6.11: - version "2.6.11" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz" - integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== +node-fetch@^2.6.12: + version "2.7.0" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -2388,15 +1842,6 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" - integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - object-inspect@^1.9.0: version "1.12.3" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" @@ -2415,13 +1860,6 @@ object-keys@^1.1.1: resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" - integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== - dependencies: - isobject "^3.0.0" - object.assign@^4.1.4: version "4.1.4" resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" @@ -2432,13 +1870,6 @@ object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" - integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== - dependencies: - isobject "^3.0.1" - on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" @@ -2516,16 +1947,6 @@ parseurl@~1.3.3: resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" - integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz" - integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== - path-exists@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" @@ -2554,13 +1975,6 @@ path-to-regexp@0.1.7: resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" @@ -2586,30 +2000,15 @@ picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - png-js@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz" integrity sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g== -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" - integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== - postcss@^8.3.11: - version "8.4.23" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz" - integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA== + version "8.4.29" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz" + integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw== dependencies: nanoid "^3.3.6" picocolors "^1.0.0" @@ -2734,14 +2133,6 @@ redis-parser@^3.0.0: dependencies: redis-errors "^1.0.0" -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - regexp.prototype.flags@^1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz" @@ -2751,16 +2142,6 @@ regexp.prototype.flags@^1.5.0: define-properties "^1.2.0" functions-have-names "^1.2.3" -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" @@ -2771,21 +2152,11 @@ resolve-from@^4.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" - integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== - restructure@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/restructure/-/restructure-2.0.1.tgz" integrity sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg== -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - reusify@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" @@ -2822,22 +2193,15 @@ safe-buffer@5.2.1: resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" - integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== - dependencies: - ret "~0.1.10" - "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sanitize-html@2.10.0: - version "2.10.0" - resolved "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.10.0.tgz" - integrity sha512-JqdovUd81dG4k87vZt6uA6YhDfWkUGruUu/aPmXLxXi45gZExnt9Bnw/qeQU8oGf82vPyaE0vO4aH0PbobB9JQ== +sanitize-html@2.11.0: + version "2.11.0" + resolved "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.11.0.tgz" + integrity sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA== dependencies: deepmerge "^4.2.2" escape-string-regexp "^4.0.0" @@ -2887,16 +2251,6 @@ serve-static@1.15.0: parseurl "~1.3.3" send "0.18.0" -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" @@ -2928,92 +2282,21 @@ signal-exit@^4.0.1: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz" integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - slash@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - standard-as-callback@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz" integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" - integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - statuses@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" @@ -3093,11 +2376,6 @@ strip-ansi@^7.0.1: dependencies: ansi-regex "^6.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" @@ -3128,21 +2406,6 @@ tiny-inflate@^1.0.0, tiny-inflate@^1.0.3: resolved "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz" integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" - integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" - integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" @@ -3150,16 +2413,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - toidentifier@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" @@ -3189,23 +2442,6 @@ ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tsconfig-paths@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tscpaths@^0.0.9: - version "0.0.9" - resolved "https://registry.npmjs.org/tscpaths/-/tscpaths-0.0.9.tgz" - integrity sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w== - dependencies: - commander "^2.20.0" - globby "^9.2.0" - tslib@^1.8.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" @@ -3243,10 +2479,10 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typescript@^4.9.5, typescript@>=2.7, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": - version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^5.2.2, typescript@>=2.7, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": + version "5.2.2" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== uhyphen@^0.2.0: version "0.2.0" @@ -3269,29 +2505,11 @@ unicode-trie@^2.0.0: pako "^0.2.5" tiny-inflate "^1.0.0" -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - unpipe@~1.0.0, unpipe@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" - integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - untildify@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz" @@ -3304,16 +2522,6 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" - integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" From 3bce81f89a9e0c77001b85b341a9f71e19e0e6e2 Mon Sep 17 00:00:00 2001 From: Eltik Date: Tue, 5 Sep 2023 16:20:25 -0400 Subject: [PATCH 02/77] Proxies working --- .gitignore | 4 +- anify-backend-recode/package.json | 3 +- .../src/database/impl/create.ts | 2 +- anify-backend-recode/src/database/impl/get.ts | 4 +- .../src/database/impl/search.ts | 4 +- .../src/database/impl/searchAdvanced.ts | 4 +- .../src/database/impl/seasonal.ts | 34 ++- anify-backend-recode/src/database/index.ts | 4 +- anify-backend-recode/src/env.ts | 20 ++ anify-backend-recode/src/helper/index.ts | 6 +- anify-backend-recode/src/index.ts | 7 +- anify-backend-recode/src/lib/impl/entry.ts | 2 +- anify-backend-recode/src/mappings/index.ts | 6 + anify-backend-recode/src/proxies/executor.ts | 31 +++ .../src/proxies/impl/checkProxies.ts | 206 ++++++++++++++++++ .../src/proxies/impl/fetchProxies.ts | 36 +++ .../src/proxies/impl/scrapeProxies.ts | 141 ++++++++++++ anify-backend-recode/src/proxies/index.ts | 17 ++ anify-backend-recode/src/types/enums.ts | 2 +- anify-backend-recode/src/types/types.ts | 2 +- anify-backend/src/helper/proxies/index.ts | 2 +- 21 files changed, 509 insertions(+), 28 deletions(-) create mode 100644 anify-backend-recode/src/env.ts create mode 100644 anify-backend-recode/src/mappings/index.ts create mode 100644 anify-backend-recode/src/proxies/executor.ts create mode 100644 anify-backend-recode/src/proxies/impl/checkProxies.ts create mode 100644 anify-backend-recode/src/proxies/impl/fetchProxies.ts create mode 100644 anify-backend-recode/src/proxies/impl/scrapeProxies.ts create mode 100644 anify-backend-recode/src/proxies/index.ts diff --git a/.gitignore b/.gitignore index fb95821..e537ed4 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,6 @@ yarn-error.log* manami.json database.json /manga -bun.lockb \ No newline at end of file +bun.lockb +goodProxies.json +proxies.json \ No newline at end of file diff --git a/anify-backend-recode/package.json b/anify-backend-recode/package.json index 4312bed..140dc16 100644 --- a/anify-backend-recode/package.json +++ b/anify-backend-recode/package.json @@ -7,7 +7,7 @@ "build": "bun build ./src/index.ts --outdir ./dist --target node", "prettier": "prettier --write .", "eslint": "eslint --ext .ts src/** --fix", - "lint": "bunx run prettier && bunx run eslint" + "lint": "bun run prettier && bun run eslint" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "latest", @@ -21,6 +21,7 @@ }, "dependencies": { "cheerio": "^1.0.0-rc.12", + "colors": "^1.4.0", "dotenv": "^16.3.1", "eventemitter2": "latest" } diff --git a/anify-backend-recode/src/database/impl/create.ts b/anify-backend-recode/src/database/impl/create.ts index e8cdb0e..b870d48 100644 --- a/anify-backend-recode/src/database/impl/create.ts +++ b/anify-backend-recode/src/database/impl/create.ts @@ -121,4 +121,4 @@ export const create = async (data: Anime | Manga) => { resolve(true); }); }); -}; \ No newline at end of file +}; diff --git a/anify-backend-recode/src/database/impl/get.ts b/anify-backend-recode/src/database/impl/get.ts index 9b2cb40..377761d 100644 --- a/anify-backend-recode/src/database/impl/get.ts +++ b/anify-backend-recode/src/database/impl/get.ts @@ -4,8 +4,8 @@ import { Anime, Manga } from "../../types/types"; export const get = async (id: string): Promise => { const anime = await db.query(`SELECT * FROM anime WHERE $id`).get({ id: id }); if (!anime) { - return await db.query(`SELECT * FROM manga WHERE $id`).get({ id: id }) as Manga | undefined; + return (await db.query(`SELECT * FROM manga WHERE $id`).get({ id: id })) as Manga | undefined; } else { return anime as Anime; } -}; \ No newline at end of file +}; diff --git a/anify-backend-recode/src/database/impl/search.ts b/anify-backend-recode/src/database/impl/search.ts index 7901813..8fbee7f 100644 --- a/anify-backend-recode/src/database/impl/search.ts +++ b/anify-backend-recode/src/database/impl/search.ts @@ -12,9 +12,9 @@ export const search = async (query: string, type: Type, formats: Format[], page: OR title->>'native' LIKE '%${query}%' OR synonyms LIKE '%${query}%' ) - ${formats?.length > 0 ? `AND "format" IN (${formats.map(f => `'${f}'`).join(', ')})` : ''} + ${formats?.length > 0 ? `AND "format" IN (${formats.map((f) => `'${f}'`).join(", ")})` : ""} `; const data = await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} ${where} ORDER BY title->>'english' ASC LIMIT ${perPage} OFFSET ${skip}`).all(); return data; -}; \ No newline at end of file +}; diff --git a/anify-backend-recode/src/database/impl/searchAdvanced.ts b/anify-backend-recode/src/database/impl/searchAdvanced.ts index 6671444..6b59dbc 100644 --- a/anify-backend-recode/src/database/impl/searchAdvanced.ts +++ b/anify-backend-recode/src/database/impl/searchAdvanced.ts @@ -12,7 +12,7 @@ export const searchAdvanced = async (query: string, type: Type, formats: Format[ OR title->>'native' LIKE '%${query}%' OR synonyms LIKE '%${query}%' ) - ${formats?.length > 0 ? `AND "format" IN (${formats.map(f => `'${f}'`).join(', ')})` : ''} + ${formats?.length > 0 ? `AND "format" IN (${formats.map((f) => `'${f}'`).join(", ")})` : ""} `; if (genres && genres.length > 0) { @@ -61,4 +61,4 @@ export const searchAdvanced = async (query: string, type: Type, formats: Format[ const data = await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} ${where} ORDER BY title->>'english' ASC LIMIT ${perPage} OFFSET ${skip}`).all(); return data; -}; \ No newline at end of file +}; diff --git a/anify-backend-recode/src/database/impl/seasonal.ts b/anify-backend-recode/src/database/impl/seasonal.ts index 7920bb4..f1a2f50 100644 --- a/anify-backend-recode/src/database/impl/seasonal.ts +++ b/anify-backend-recode/src/database/impl/seasonal.ts @@ -10,29 +10,45 @@ export const seasonal = async (trending: Anime[] | Manga[], popular: Anime[] | M seasonal: seasonal.map((a) => String(a.id)), }; - const trend = await db.query(` + const trend = (await db + .query( + ` SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} WHERE id IN (${ids.trending.map((id) => `'${id}'`).join(", ")}) ORDER BY title->>'english' ASC - `).all() as Anime[] | Manga[]; + `, + ) + .all()) as Anime[] | Manga[]; - const pop = await db.query(` + const pop = (await db + .query( + ` SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} WHERE id IN (${ids.popular.map((id) => `'${id}'`).join(", ")}) ORDER BY title->>'english' ASC - `).all() as Anime[] | Manga[]; + `, + ) + .all()) as Anime[] | Manga[]; - const t = await db.query(` + const t = (await db + .query( + ` SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} WHERE id IN (${ids.top.map((id) => `'${id}'`).join(", ")}) ORDER BY title->>'english' ASC - `).all() as Anime[] | Manga[]; + `, + ) + .all()) as Anime[] | Manga[]; - const season = await db.query(` + const season = (await db + .query( + ` SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} WHERE id IN (${ids.seasonal.map((id) => `'${id}'`).join(", ")}) ORDER BY title->>'english' ASC - `).all() as Anime[] | Manga[]; + `, + ) + .all()) as Anime[] | Manga[]; trend.map((media) => { media.characters = []; @@ -48,4 +64,4 @@ export const seasonal = async (trending: Anime[] | Manga[], popular: Anime[] | M }); return { trending: trend, popular: pop, top: t, seasonal: season }; -}; \ No newline at end of file +}; diff --git a/anify-backend-recode/src/database/index.ts b/anify-backend-recode/src/database/index.ts index ddafbfb..216729e 100644 --- a/anify-backend-recode/src/database/index.ts +++ b/anify-backend-recode/src/database/index.ts @@ -2,7 +2,7 @@ import { Database } from "bun:sqlite"; export const db = new Database("db.sqlite"); -export const init = async() => { +export const init = async () => { const anime = ` CREATE TABLE IF NOT EXISTS anime ( id TEXT PRIMARY KEY, @@ -90,4 +90,4 @@ export const init = async() => { await db.query(manga).run(); await db.query(skipTimes).run(); await db.query(apiKey).run(); -}; \ No newline at end of file +}; diff --git a/anify-backend-recode/src/env.ts b/anify-backend-recode/src/env.ts new file mode 100644 index 0000000..4a18604 --- /dev/null +++ b/anify-backend-recode/src/env.ts @@ -0,0 +1,20 @@ +// All environment variables. +export const env = { + PORT: Number(process.env.PORT) || 3000, + DATABASE_TYPE: process.env.DATABASE_TYPE || "postgres", + DATABASE_URL: process.env.DATABASE_URL, + NINEANIME_RESOLVER: process.env.NINEANIME_RESOLVER, + NINEANIME_KEY: process.env.NINEANIME_KEY, + REDIS_URL: process.env.REDIS_URL, + REDIS_CACHE_TIME: Number(process.env.REDIS_CACHE_TIME) || 60 * 60 * 24 * 7, + USE_API_KEYS: process.env.USE_API_KEYS || "false", + MASTER_KEY: process.env.MASTER_KEY, + API_KEY_WHITELIST: process.env.API_KEY_WHITELIST?.split(",") || [], + CENSYS_ID: process.env.CENSYS_ID, + CENSYS_SECRET: process.env.CENSYS_SECRET, + SIMKL_CLIENT_ID: process.env.SIMKL_CLIENT_ID, + SIMKL_CLIENT_SECRET: process.env.SIMKL_CLIENT_SECRET, + USE_MIXDROP: process.env.USE_MIXDROP === "true" || false, + MIXDROP_EMAIL: process.env.MIXDROP_EMAIL, + MIXDROP_KEY: process.env.MIXDROP_KEY, +}; diff --git a/anify-backend-recode/src/helper/index.ts b/anify-backend-recode/src/helper/index.ts index 84ba278..09820a1 100644 --- a/anify-backend-recode/src/helper/index.ts +++ b/anify-backend-recode/src/helper/index.ts @@ -1,3 +1,7 @@ +export function isString(object: unknown): object is string { + return typeof object === "string"; +} + export function setIntervalImmediately(func: () => Promise, interval: number) { func(); return setInterval(async () => { @@ -20,4 +24,4 @@ export const averageMetric = (object: any) => { } return validCount === 0 ? 0 : Number.parseFloat((average / validCount).toFixed(2)); -}; \ No newline at end of file +}; diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 8a12299..54ecdd3 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -4,7 +4,8 @@ dotenv.config(); import { search } from "./database/impl/search"; import { Type } from "./types/enums"; import { init } from "./database"; +import { scrapeCorsProxies } from "./proxies/impl/scrapeProxies"; +import { checkCorsProxies } from "./proxies/impl/checkProxies"; +import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; -init().then((data) => { - search("Mushoku Tensei", Type.ANIME, [], 0, 10).then(console.log) -}) \ No newline at end of file +fetchCorsProxies().then(console.log); diff --git a/anify-backend-recode/src/lib/impl/entry.ts b/anify-backend-recode/src/lib/impl/entry.ts index c34c990..473c294 100644 --- a/anify-backend-recode/src/lib/impl/entry.ts +++ b/anify-backend-recode/src/lib/impl/entry.ts @@ -25,4 +25,4 @@ export const createEntry = async (data: { toInsert: Anime | Manga; type: Type }) await emitter.emitAsync(Events.COMPLETED_ENTRY_CREATION, data.toInsert); return data.toInsert; -}; \ No newline at end of file +}; diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend-recode/src/mappings/index.ts new file mode 100644 index 0000000..c0a4c4a --- /dev/null +++ b/anify-backend-recode/src/mappings/index.ts @@ -0,0 +1,6 @@ +const ANIME_PROVIDERS: any[] = []; +const MANGA_PROVIDERS: any[] = []; +const META_PROVIDERS: any[] = []; +const INFORMATION_PROVIDERS: any[] = []; + +export { ANIME_PROVIDERS, MANGA_PROVIDERS, INFORMATION_PROVIDERS, META_PROVIDERS }; diff --git a/anify-backend-recode/src/proxies/executor.ts b/anify-backend-recode/src/proxies/executor.ts new file mode 100644 index 0000000..3372ae7 --- /dev/null +++ b/anify-backend-recode/src/proxies/executor.ts @@ -0,0 +1,31 @@ +export default class ChunkedExecutor { + private items: T[]; + private chunkSize: number; + private executor: (item: T) => Promise; + private perChunkCallback?: (chunk: T[]) => void; + private perResultCallback?: (result: R[]) => void; + constructor(items: T[], chunkSize: number, executor: (item: T) => Promise, perChunkCallback?: (chunk: T[]) => void, perResultCallback?: (result: R[]) => void) { + this.items = items; + this.chunkSize = chunkSize; + this.executor = executor; + this.perChunkCallback = perChunkCallback; + this.perResultCallback = perResultCallback; + } + + public async execute(): Promise { + const results: R[] = []; + for (let i = 0; i < this.items.length; i += this.chunkSize) { + const chunk = this.items.slice(i, i + this.chunkSize); + if (this.perChunkCallback) { + this.perChunkCallback(chunk); + } + const promises = chunk.map((item) => this.executor(item)); + const chunkResults = await Promise.all(promises); + results.push(...chunkResults.filter((result) => result !== null)); + if (this.perResultCallback) { + this.perResultCallback(results); + } + } + return results; + } +} diff --git a/anify-backend-recode/src/proxies/impl/checkProxies.ts b/anify-backend-recode/src/proxies/impl/checkProxies.ts new file mode 100644 index 0000000..9f6e6cb --- /dev/null +++ b/anify-backend-recode/src/proxies/impl/checkProxies.ts @@ -0,0 +1,206 @@ +import colors from "colors"; +import { isString } from "../../helper"; +import ChunkedExecutor from "../executor"; +import { CORS_PROXIES } from ".."; +import { ANIME_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS } from "../../mappings"; + +const toCheck: string[] = []; + +export async function checkCorsProxies(): Promise { + const goodIps: string[] = []; + console.log(colors.yellow("Importing proxies... Please note that reading the proxies file may take a while.")); + if (toCheck.length === 0) { + const file = Bun.file("./proxies.json"); + if (file) { + // Check proxies.json + const proxies = await file.json(); + for (let i = 0; i < proxies.length; i++) { + const ip = proxies[i].ip; + const port = proxies[i].port; + + const url = `http://${ip}:${port}`; + toCheck.push(url); + } + console.log(colors.green("Finished importing current proxies.")); + } + } + console.log(colors.yellow("Checking proxies...")); + const ips = toCheck + .map((proxy) => { + try { + const url = new URL(proxy); + return { ip: url.hostname, port: Number(url.port) }; + } catch (e) { + return { ip: "", port: 8080 }; + } + }) + .filter((obj) => obj.port != 8080); + + const chunkSize = 25; + const perChunkCallback = (chunk: IP[]) => { + console.log(colors.gray(`Checking ${chunk.length} proxies...`)); + }; + + const perResultsCallback = (result: (string | undefined)[]) => { + const ips = result.filter(isString); + goodIps.push(...ips); + console.log(colors.green(`${ips.length} proxies are good!`)); + + Bun.write("./goodProxies.json", JSON.stringify(goodIps, null, 4)); + }; + + const executor = new ChunkedExecutor(ips, chunkSize, makeRequest, perChunkCallback, perResultsCallback); + await executor.execute(); + + console.log(colors.gray("Finished checking proxies.")); + + CORS_PROXIES.length = 0; + toCheck.length = 0; + CORS_PROXIES.push(...goodIps); + return goodIps; +} + +async function makeRequest(ip: IP): Promise { + const timeout = 3000; + const controller = new AbortController(); + const id = setTimeout(() => controller.abort(), timeout); + + try { + const response = await fetch(`http://${ip.ip}:${ip.port}/iscorsneeded`, { + signal: controller.signal, + }); + if (response.status === 200 && (await response.text()) === "no") { + const secondResponse = await fetch(`http://${ip.ip}:${ip.port}/https://graphql.anilist.co`, { + signal: controller.signal, + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + Origin: "graphql.anilist.co", + }, + body: JSON.stringify({ + query: `query ($id: Int) { + Media (id: $id) { + id + title { + romaji + english + native + } + } + }`, + variables: { + id: 21, + }, + }), + }).catch((err) => { + return null; + }); + + clearTimeout(id); + if (secondResponse?.ok) { + let text: any = undefined; + + try { + text = await secondResponse.json(); + } catch (e) { + console.log(colors.red(`Error parsing JSON from ${ip.ip}:${ip.port}: ${e}`)); + } + + if (!text) { + return undefined; + } + + let isOkay = true; + + for (const provider of ANIME_PROVIDERS) { + console.log(colors.gray("Testing ") + provider.id + colors.gray(".")); + + provider.customProxy = `http://${ip.ip}:${ip.port}`; + + const providerResponse = await provider.search("Mushoku Tensei").catch(() => { + return undefined; + }); + + if (!providerResponse) { + console.log(colors.red(`${provider.id} failed.`)); + isOkay = false; + provider.customProxy = undefined; + break; + } + + provider.customProxy = undefined; + } + + if (isOkay) { + console.log(colors.yellow("Anime providers passed.")); + } else { + console.log(colors.red("Anime providers failed.")); + return undefined; + } + + for (const provider of MANGA_PROVIDERS) { + console.log(colors.gray("Testing ") + provider.id + colors.gray(".")); + + provider.customProxy = `http://${ip.ip}:${ip.port}`; + + const providerResponse = await provider.search("Mushoku Tensei").catch(() => { + return undefined; + }); + + if (!providerResponse) { + isOkay = false; + provider.customProxy = undefined; + break; + } + + provider.customProxy = undefined; + } + + if (isOkay) { + console.log(colors.yellow("Manga providers passed.")); + } else { + console.log(colors.red("Manga providers failed.")); + return undefined; + } + + for (const provider of META_PROVIDERS) { + console.log(colors.gray("Testing ") + provider.id + colors.gray(".")); + + provider.customProxy = `http://${ip.ip}:${ip.port}`; + + const providerResponse = await provider.search("Mushoku Tensei").catch(() => { + return undefined; + }); + + if (!providerResponse) { + isOkay = false; + provider.customProxy = undefined; + break; + } + + provider.customProxy = undefined; + } + + if (isOkay) { + console.log(colors.yellow("Meta providers passed.")); + return ip.ip + ":" + ip.port; + } else { + console.log(colors.red("Meta providers failed.")); + return undefined; + } + } else { + return undefined; + } + } else { + return undefined; + } + } catch (error) { + return undefined; + } +} + +interface IP { + ip: string; + port: number; +} diff --git a/anify-backend-recode/src/proxies/impl/fetchProxies.ts b/anify-backend-recode/src/proxies/impl/fetchProxies.ts new file mode 100644 index 0000000..6415c73 --- /dev/null +++ b/anify-backend-recode/src/proxies/impl/fetchProxies.ts @@ -0,0 +1,36 @@ +import colors from "colors"; +import { CORS_PROXIES } from ".."; + +export async function fetchCorsProxies(): Promise { + const file = Bun.file("./goodProxies.json"); + if (file) { + const BATCH_SIZE = 100; + + const proxyData = await file.json(); + const totalProxies = proxyData.length; + let currentIndex = 0; + + while (currentIndex < totalProxies) { + const proxiesToAdd: string[] = []; + + for (let i = 0; i < BATCH_SIZE && currentIndex < totalProxies; i++, currentIndex++) { + const proxy = proxyData[currentIndex]; + + if (!proxy.startsWith("http")) { + proxiesToAdd.push(`http://${proxy}`); + } else { + proxiesToAdd.push(proxy); + } + } + + console.log(colors.yellow(`Adding ${proxiesToAdd.length} proxies to the list.`)); + + CORS_PROXIES.push(...proxiesToAdd); + } + + console.log(colors.green("Finished importing proxies.")); + } else { + return []; + } + return CORS_PROXIES; +} diff --git a/anify-backend-recode/src/proxies/impl/scrapeProxies.ts b/anify-backend-recode/src/proxies/impl/scrapeProxies.ts new file mode 100644 index 0000000..9fbfc8c --- /dev/null +++ b/anify-backend-recode/src/proxies/impl/scrapeProxies.ts @@ -0,0 +1,141 @@ +import colors from "colors"; +import { toCheck } from ".."; +import { checkCorsProxies } from "./checkProxies"; +import { env } from "../../env"; + +export async function scrapeCorsProxies(): Promise { + const hits: { ip: string; port: number }[] = []; + let cursor: any = null; // Initialize cursor as null + const maxRequests = 50; + let currentRequest = 0; + + console.log(colors.yellow("Searching for proxies on Censys...")); + + try { + do { + const data = await search("c7d96235df80ea051e9d57f3ab6d3e4da289fd3b", cursor); + if (!data) { + break; + } + + data.result.hits.filter((hit) => { + hit.services.some((service) => { + if (service.extended_service_name === "HTTP" || service.extended_service_name === "HTTPS") { + hits.push({ ip: hit.ip, port: service.port }); + } + }); + }); + + console.log(colors.gray("Fetched ") + colors.blue(hits.length + "") + colors.gray(" hits so far.")); + + cursor = data.result.links.next; + currentRequest++; + + // Break the loop if cursor is null or empty string, or maxRequests limit is reached + if (cursor === null || cursor === "" || currentRequest >= maxRequests) { + console.log(colors.gray("Finished fetching proxies from Censys.")); + + await Bun.write("./proxies.json", JSON.stringify(hits, null, 4)); + toCheck.push(...hits.map((hit) => `http://${hit.ip}:${hit.port}`)); + + await checkCorsProxies(); + break; + } + } while (cursor !== null && cursor !== "" && currentRequest < maxRequests); + } catch (error) { + // Handle the error if necessary + console.error(error); + } +} + +async function search(q: string, cursor: string | null = null): Promise { + const appendCursor = cursor ? `&cursor=${cursor}` : ""; + + const url = "/hosts/search?q=" + q + `&per_page=100&virtual_hosts=EXCLUDE` + appendCursor; + + if (!env.CENSYS_ID || !env.CENSYS_SECRET) { + console.log(colors.yellow("CENSYS_ID or CENSYS_SECRET not found in .env file. Please add them to scrape CORS proxies.")); + return undefined; + } + + const apiID = env.CENSYS_ID ?? "d973cf60-4ce4-4746-962b-815ddfdebf80", + apiSecret = env.CENSYS_SECRET ?? "s6EUuA4Sfaajd8jDBJ17b4DaoPofjDe6"; + + const auth = "Basic " + Buffer.from(apiID + ":" + apiSecret).toString("base64"); + const headers = { Authorization: auth }; + + const data = await ( + await fetch(`https://search.censys.io/api/v2${url}`, { + headers: headers, + }) + ).json(); + return data; +} + +interface Root { + code: number; + status: string; + result: Result; +} + +interface Result { + query: string; + total: number; + duration: number; + hits: Hit[]; + links: Links; +} + +interface Hit { + ip: string; + services: Service[]; + location: Location; + autonomous_system: AutonomousSystem; + last_updated_at: string; + dns?: Dns; +} + +interface Service { + port: number; + service_name: string; + extended_service_name: string; + transport_protocol: string; + certificate?: string; +} + +interface Location { + continent: string; + country: string; + country_code: string; + city: string; + postal_code?: string; + timezone: string; + coordinates: Coordinates; + province?: string; +} + +interface Coordinates { + latitude: number; + longitude: number; +} + +interface AutonomousSystem { + asn: number; + description: string; + bgp_prefix: string; + name: string; + country_code: string; +} + +interface Dns { + reverse_dns: ReverseDns; +} + +interface ReverseDns { + names: string[]; +} + +interface Links { + next: string; + prev: string; +} diff --git a/anify-backend-recode/src/proxies/index.ts b/anify-backend-recode/src/proxies/index.ts new file mode 100644 index 0000000..4d340ec --- /dev/null +++ b/anify-backend-recode/src/proxies/index.ts @@ -0,0 +1,17 @@ +/** + * @description Handles the scraping of CORS proxies. + */ + +import colors from "colors"; +import { existsSync, writeFileSync } from "fs"; +import { readFile, writeFile } from "fs/promises"; +import { join } from "path"; +import ChunkedExecutor from "./executor"; +import { isString } from "../helper"; +import { ANIME_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS } from "../mappings"; +import { env } from "bun"; + +// List of CORS proxies +export const CORS_PROXIES: string[] = []; + +export const toCheck: string[] = []; diff --git a/anify-backend-recode/src/types/enums.ts b/anify-backend-recode/src/types/enums.ts index 8527ea8..8c9e4e0 100644 --- a/anify-backend-recode/src/types/enums.ts +++ b/anify-backend-recode/src/types/enums.ts @@ -127,4 +127,4 @@ export const enum StreamingServers { DuckStreamV2 = "duckstreamv2", BirdStream = "birdstream", AnimeFlix = "animeflix", -} \ No newline at end of file +} diff --git a/anify-backend-recode/src/types/types.ts b/anify-backend-recode/src/types/types.ts index a99c698..1bff926 100644 --- a/anify-backend-recode/src/types/types.ts +++ b/anify-backend-recode/src/types/types.ts @@ -189,4 +189,4 @@ export type Result = { format: Format; img: string | null; providerId: string; -}; \ No newline at end of file +}; diff --git a/anify-backend/src/helper/proxies/index.ts b/anify-backend/src/helper/proxies/index.ts index 48c865c..ee87ad1 100644 --- a/anify-backend/src/helper/proxies/index.ts +++ b/anify-backend/src/helper/proxies/index.ts @@ -6,7 +6,7 @@ import ChunkedExecutor from "../executor"; import cluster from "node:cluster"; import { isString } from ".."; import { ANIME_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS } from "../../mapping"; -import { env } from "process"; +import { env } from "../../env"; // List of CORS proxies export const CORS_PROXIES: string[] = []; From cd522e29446d3665c2cdbb8ff94d9a8d091645e9 Mon Sep 17 00:00:00 2001 From: Eltik Date: Tue, 5 Sep 2023 16:41:08 -0400 Subject: [PATCH 03/77] Added extractor stuff --- anify-backend-recode/package.json | 2 + anify-backend-recode/src/helper/extractor.ts | 567 ++++++++++++++++++ anify-backend-recode/src/helper/index.ts | 10 + anify-backend-recode/src/helper/request.ts | 83 +++ anify-backend-recode/src/index.ts | 12 +- anify-backend-recode/src/lib/event.ts | 14 - anify-backend-recode/src/lib/impl/entry.ts | 2 +- anify-backend-recode/src/lib/index.ts | 14 + .../src/mappings/impl/anime/index.ts | 36 ++ .../src/mappings/impl/anime/nineanime.ts | 349 +++++++++++ anify-backend-recode/src/proxies/index.ts | 10 - anify-backend-recode/src/types/enums.ts | 2 + 12 files changed, 1070 insertions(+), 31 deletions(-) create mode 100644 anify-backend-recode/src/helper/extractor.ts create mode 100644 anify-backend-recode/src/helper/request.ts delete mode 100644 anify-backend-recode/src/lib/event.ts create mode 100644 anify-backend-recode/src/mappings/impl/anime/index.ts create mode 100644 anify-backend-recode/src/mappings/impl/anime/nineanime.ts diff --git a/anify-backend-recode/package.json b/anify-backend-recode/package.json index 140dc16..5f2f085 100644 --- a/anify-backend-recode/package.json +++ b/anify-backend-recode/package.json @@ -10,6 +10,7 @@ "lint": "bun run prettier && bun run eslint" }, "devDependencies": { + "@types/crypto-js": "^4.1.2", "@typescript-eslint/eslint-plugin": "latest", "@typescript-eslint/parser": "latest", "bun-types": "latest", @@ -22,6 +23,7 @@ "dependencies": { "cheerio": "^1.0.0-rc.12", "colors": "^1.4.0", + "crypto-js": "^4.1.1", "dotenv": "^16.3.1", "eventemitter2": "latest" } diff --git a/anify-backend-recode/src/helper/extractor.ts b/anify-backend-recode/src/helper/extractor.ts new file mode 100644 index 0000000..db96a22 --- /dev/null +++ b/anify-backend-recode/src/helper/extractor.ts @@ -0,0 +1,567 @@ +import CryptoJS from "crypto-js"; +import { load } from "cheerio"; +import { substringAfter, substringBefore } from "."; +import { env } from "process"; +import { Source } from "../types/types"; +import { StreamingServers } from "../types/enums"; + +export default class Extractor { + private url: string; + private result: Source; + + constructor(url: string, result: Source) { + this.url = url; + this.result = result; + } + + async extract(server: StreamingServers): Promise { + switch (server) { + case StreamingServers.GogoCDN: + return await this.extractGogoCDN(this.url, this.result); + case StreamingServers.StreamSB: + return await this.extractStreamSB(this.url, this.result); + case StreamingServers.VidCloud: + return await this.extractVidCloud(this.url, this.result); + case StreamingServers.VidStreaming: + return await this.extractGogoCDN(this.url, this.result); + case StreamingServers.StreamTape: + return await this.extractStreamTape(this.url, this.result); + case StreamingServers.MyCloud: + return await this.extractMyCloud(this.url, this.result); + case StreamingServers.Filemoon: + return await this.extractFileMoon(this.url, this.result); + case StreamingServers.VizCloud: + return await this.extractVizCloud(this.url, this.result); + case StreamingServers.Kwik: + return await this.extractKwik(this.url, this.result); + case StreamingServers.AllAnime: + return await this.extractAllAnime(this.url, this.result); + case StreamingServers.AnimeFlix: + return await this.extractAnimeFlix(this.url, this.result); + default: + return undefined; + } + } + + public async extractAnimeFlix(url: string, result: Source): Promise { + const data = await ( + await fetch(url, { + headers: { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36", + }, + }) + ).text(); + + const $ = load(data); + // const source = 'https://cdn.discordapp.com/attachments/1126579073980846132/1141026618941382696/1080p-ROCK.m3u8'; + /* + var options = { + video: plyrplayer, + subUrl: JSON.parse('[{"url":"https://proxy.gogocden.site/https://cdn.discordapp.com/attachments/1126579089524932669/1141026620472315946/ENG.ass","title":"ENG","lang":"ENG"}]').find(sub => sub.title === name)?.url, + fonts: ['/public/trebuc.woff2', '/public/AdobeArabic-Bold.woff2'], + workerUrl: '/public/subtitle-worker.js', + legacyWorkerUrl: '/public/subtitle-worker-legacy.js' + }; + */ + + const source = $.html().split("const source = '")[1].split("';")[0]; + if (source.includes("https://cdn.discordapp.com")) { + result.sources.push({ + quality: "1080p", + url: source, + }); + } else { + result.sources.push({ + quality: "auto", + url: source, + }); + + const req = await fetch(source, { + headers: { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36", + Referer: "https://api.animeflix.live", + }, + }); + + const resolutions = (await req.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); + resolutions?.forEach((res: string) => { + const index = source.lastIndexOf("/"); + const quality = res.split("\n")[0].split("x")[1].split(",")[0]; + const url = source.slice(0, index); + result.sources.push({ + url: url + "/" + res.split("\n")[1], + quality: quality + "p", + }); + }); + } + + try { + const subtitles = JSON.parse($.html().split("instance.setTrackByUrl(JSON.parse(`")[1].split("`).find")[0]); + subtitles.map((subtitle: { title: string; lang: string; url: string }) => { + result.subtitles.push({ + label: subtitle.title, + lang: subtitle.lang, + url: subtitle.url, + }); + }); + } catch (e) { + // + } + + return result; + } + + public async extractMyCloud(url: string, result: Source): Promise { + const proxy = env.NINEANIME_RESOLVER || "https://9anime.resolver.net"; + const proxyKey: string = env.NINEANIME_KEY || `9anime`; + + const lolToken = await (await fetch("https://mcloud.to/futoken")).text(); + + const m3u8Req = await fetch(`${proxy}/rawMcloud?apikey=${proxyKey}`, { + method: "POST", + body: JSON.stringify({ + query: url, + futoken: lolToken, + }), + headers: { + "Content-Type": "application/json", + }, + }); + const data = await m3u8Req.json(); + + const m3u8File = data.rawURL; + + const mainReq = await ( + await fetch(m3u8File, { + headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, + }) + ).json(); + + for (const track of mainReq.result?.tracks ?? []) { + result.subtitles.push({ + url: track.file, + lang: track.label ? track.label : track.kind, + label: track.kind, + }); + } + + const file = mainReq.result?.sources[0]?.file; + + const req = await fetch(file, { + headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, + }); + + const resolutions = (await req.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); + resolutions?.forEach((res: string) => { + const index = file.lastIndexOf("/"); + const quality = res.split("\n")[0].split("x")[1].split(",")[0]; + const url = file.slice(0, index); + result.sources.push({ + url: url + "/" + res.split("\n")[1], + quality: quality + "p", + }); + }); + + // Master m3u8 file + result.sources.push({ + quality: "auto", + url: file, + }); + + //result.headers = {}; // TEMP doesnt require proxy + + return result; + } + + public async extractFileMoon(url: string, result: Source): Promise { + const proxy = env.NINEANIME_RESOLVER || "https://9anime.resolver.com"; + const proxyKey: string = env.NINEANIME_KEY || `9anime`; + const data = await (await fetch(`https://filemoon.sx/d/${url}`)).text(); + + const resolver = await fetch(`${proxy}/filemoon?apikey=${proxyKey}`, { + method: "POST", + body: JSON.stringify({ + query: data, + }), + }); + + const resolverData = await resolver.json(); + + result.sources.push({ + url: resolverData.url, + quality: "auto", + }); + + const resReq = await fetch(resolverData.url, { headers: { Referer: "https://9anime.pl" } }); + const resolutions = (await resReq.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); + + resolutions?.forEach((res: string) => { + const index = resolverData.url.lastIndexOf("/"); + const quality = res.split("\n")[0].split("x")[1].split(",")[0]; + const url = resolverData.url.slice(0, index); + + result.sources.push({ + url: url + "/" + res.split("\n")[1], + quality: quality + "p", + }); + }); + + return result; + } + + /** + * @description Requires a VizStream ID. Uses NineAnime resolver. + * @param vidStreamId VizStream ID + * @returns Promise + */ + public async extractVizCloud(url: string, result: Source): Promise { + const proxy = env.NINEANIME_RESOLVER || "https://9anime.resolver.net"; + const proxyKey: string = env.NINEANIME_KEY || `9anime`; + + const lolToken = await (await fetch("https://vidstream.pro/futoken")).text(); + + const m3u8Req = await fetch(`${proxy}/rawVizcloud?apikey=${proxyKey}`, { + method: "POST", + body: JSON.stringify({ + query: url, + futoken: lolToken, + }), + headers: { + "Content-Type": "application/json", + }, + }); + const data = await m3u8Req.json(); + + const m3u8File = data.rawURL; + + const mainReq = await ( + await fetch(m3u8File, { + headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, + }) + ).json(); + + for (const track of mainReq.result?.tracks ?? []) { + result.subtitles.push({ + url: track.file, + lang: track.label ? track.label : track.kind, + label: track.kind, + }); + } + + const file = mainReq.result?.sources[0]?.file; + + const req = await fetch(file, { + headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, + }); + + const resolutions = (await req.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); + resolutions?.forEach((res: string) => { + const index = file.lastIndexOf("/"); + const quality = res.split("\n")[0].split("x")[1].split(",")[0]; + const url = file.slice(0, index); + result.sources.push({ + url: url + "/" + res.split("\n")[1], + quality: quality + "p", + }); + }); + + // Master m3u8 file + result.sources.push({ + quality: "auto", + url: file, + }); + + //result.headers = {}; // TEMP doesnt require proxy + + return result; + } + + public async extractGogoCDN(url: string, result: Source): Promise { + const keys = { + key: CryptoJS.enc.Utf8.parse("37911490979715163134003223491201"), + secondKey: CryptoJS.enc.Utf8.parse("54674138327930866480207815084989"), + iv: CryptoJS.enc.Utf8.parse("3134003223491201"), + }; + + const req = await fetch(url); + const $ = load(await req.text()); + + const encyptedParams = await generateEncryptedAjaxParams(new URL(url).searchParams.get("id") ?? ""); + + const encryptedData = await fetch(`${new URL(url).protocol}//${new URL(url).hostname}/encrypt-ajax.php?${encyptedParams}`, { + headers: { + "X-Requested-With": "XMLHttpRequest", + }, + }); + + const decryptedData = await decryptAjaxData((await encryptedData.json())?.data); + if (!decryptedData.source) throw new Error("No source found. Try a different server."); + + if (decryptedData.source[0].file.includes(".m3u8")) { + const resResult = await fetch(decryptedData.source[0].file.toString()); + const resolutions = (await resResult.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); + + resolutions?.forEach((res: string) => { + const index = decryptedData.source[0].file.lastIndexOf("/"); + const quality = res.split("\n")[0].split("x")[1].split(",")[0]; + const url = decryptedData.source[0].file.slice(0, index); + + result.sources.push({ + url: url + "/" + res.split("\n")[1], + quality: quality + "p", + }); + }); + + decryptedData.source.forEach((source: any) => { + result.sources.push({ + url: source.file, + quality: "default", + }); + }); + } else { + decryptedData.source.forEach((source: any) => { + result.sources.push({ + url: source.file, + quality: source.label.split(" ")[0] + "p", + }); + }); + + decryptedData.source_bk.forEach((source: any) => { + result.sources.push({ + url: source.file, + quality: "backup", + }); + }); + } + + return result; + + function generateEncryptedAjaxParams(id: string) { + const encryptedKey = CryptoJS.AES.encrypt(id, keys.key, { + iv: keys.iv, + }); + + const scriptValue = $("script[data-name='episode']").data().value as string; + + const decryptedToken = CryptoJS.AES.decrypt(scriptValue, keys.key, { + iv: keys.iv, + }).toString(CryptoJS.enc.Utf8); + + return `id=${encryptedKey}&alias=${id}&${decryptedToken}`; + } + + function decryptAjaxData(encryptedData: string) { + const decryptedData = CryptoJS.enc.Utf8.stringify( + CryptoJS.AES.decrypt(encryptedData, keys.secondKey, { + iv: keys.iv, + }), + ); + + return JSON.parse(decryptedData); + } + } + + public async extractStreamSB(url: string, result: Source): Promise { + throw new Error("Method not implemented yet."); + } + + public async extractVidCloud(url: string, result: Source): Promise { + const host = "https://megacloud.tv"; + const id = url.split("/").pop()?.split("?")[0]; + + const options = { + headers: { + "X-Requested-With": "XMLHttpRequest", + Referer: url, + }, + }; + + const request = await fetch(`${host}/embed-2/ajax/e-1/getSources?id=${id}`, { + headers: { + "X-Requested-With": "XMLHttpRequest", + }, + }); + + const reqData = await request.json(); + + const { tracks, intro, outro } = reqData; + let { sources } = reqData; + + const req = await fetch("https://github.com/enimax-anime/key/blob/e6/key.txt"); + + const data = await req.text(); + let decryptKey = substringBefore(substringAfter(data, '"blob-code blob-code-inner js-file-line">'), ""); + if (!decryptKey) { + decryptKey = await (await fetch("https://raw.githubusercontent.com/enimax-anime/key/e6/key.txt")).json(); + } + + const encryptedURLTemp = sources.split(""); + + let key = ""; + + for (const index of decryptKey) { + for (let i = Number(index[0]); i < Number(index[1]); i++) { + key += encryptedURLTemp[i]; + encryptedURLTemp[i] = null; + } + } + + sources = encryptedURLTemp.filter((x: any) => x !== null).join(""); + + try { + sources = JSON.parse(CryptoJS.AES.decrypt(sources, key).toString(CryptoJS.enc.Utf8)); + } catch { + sources = null; + } + + if (!sources) { + return result; + } + + for (const source of sources) { + if (source.type === "hls") { + const data = await (await fetch(source.file)).text(); + + const resolutions = data.match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); + + resolutions?.forEach((res: string) => { + const index = source.file.lastIndexOf("/"); + const quality = res.split("\n")[0].split("x")[1].split(",")[0]; + const url = source.file.slice(0, index); + + result.sources.push({ + url: url + "/" + res.split("\n")[1], + quality: quality + "p", + }); + }); + } + + if (intro.end > 1) { + result.intro = { + start: intro.start, + end: intro.end, + }; + } + if (outro.end > 1) { + result.outro = { + start: outro.start, + end: outro.end, + }; + } + } + + result.sources.push({ + url: sources[0].file, + quality: "auto", + }); + + result.subtitles = tracks?.map((s: any) => ({ + url: s.file, + lang: s.label ? s.label : "Thumbnails", + })); + + return result; + } + + public async extractKwik(url: string, result: Source): Promise { + const host = "https://animepahe.com"; // Subject to change maybe. + const req = await fetch(url, { headers: { Referer: host } }); + const match = load(await req.text()) + .html() + .match(/p\}.*kwik.*/g); + if (!match) { + throw new Error("Video not found."); + } + let arr: string[] = match[0].split("return p}(")[1].split(","); + + const l = arr.slice(0, arr.length - 5).join(""); + arr = arr.slice(arr.length - 5, -1); + arr.unshift(l); + + const [p, a, c, k, e, d] = arr.map((x) => x.split(".sp")[0]); + + const formatted = format(p, a, c, k, e, {}); + + const source = formatted + .match(/source=\\(.*?)\\'/g)[0] + .replace(/\'/g, "") + .replace(/source=/g, "") + .replace(/\\/g, ""); + + result.sources.push({ + url: source, + quality: "auto", + }); + + return result; + + function format(p: any, a: any, c: any, k: any, e: any, d: any) { + k = k.split("|"); + e = (c: any) => { + return (c < a ? "" : e(parseInt((c / a).toString()))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)); + }; + if (!"".replace(/^/, String)) { + while (c--) { + d[e(c)] = k[c] || e(c); + } + k = [ + (e: any) => { + return d[e]; + }, + ]; + e = () => { + return "\\w+"; + }; + c = 1; + } + while (c--) { + if (k[c]) { + p = p.replace(new RegExp("\\b" + e(c) + "\\b", "g"), k[c]); + } + } + return p; + } + } + + public async extractStreamTape(url: string, result: Source): Promise { + throw new Error("Method not implemented yet."); + } + + public async extractFPlayer(url: string, result: Source): Promise { + throw new Error("Method not implemented yet."); + } + + public async extractAllAnime(url: string, result: Source): Promise { + const allAnimeApiUrl = "https://www.allanimenews.com"; + + const iframeUrl = `${allAnimeApiUrl}${url}`; + + const data = await (await fetch(iframeUrl)).json(); + const link: string = data.links[0].src; + + if (!link) return result; + + const m3u8 = await (await fetch(link)).text(); + + const resolutions = m3u8.match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); + + resolutions?.forEach((res: string) => { + const quality = res.split("\n")[0].split("x")[1].split(",")[0]; + + const uri = new URL(link); + const url = uri.protocol + "//" + uri.hostname; + + result.sources.push({ + url: url + res.split("\n")[1], + quality: quality + "p", + }); + }); + + result.sources.push({ + url: link, + quality: "auto", + }); + + return result; + } +} diff --git a/anify-backend-recode/src/helper/index.ts b/anify-backend-recode/src/helper/index.ts index 09820a1..68e61c7 100644 --- a/anify-backend-recode/src/helper/index.ts +++ b/anify-backend-recode/src/helper/index.ts @@ -1,3 +1,13 @@ +export function substringBefore(str: string, toFind: string) { + const index = str.indexOf(toFind); + return index == -1 ? "" : str.substring(0, index); +} + +export function substringAfter(str: string, toFind: string) { + const index = str.indexOf(toFind); + return index == -1 ? "" : str.substring(index + toFind.length); +} + export function isString(object: unknown): object is string { return typeof object === "string"; } diff --git a/anify-backend-recode/src/helper/request.ts b/anify-backend-recode/src/helper/request.ts new file mode 100644 index 0000000..7475088 --- /dev/null +++ b/anify-backend-recode/src/helper/request.ts @@ -0,0 +1,83 @@ +import { CORS_PROXIES } from "../proxies"; +import colors from "colors"; + +export default class Http { + private static bannedProxies: string[] = []; + public static unbannedProxies: string[] = CORS_PROXIES; + + static updateBannedProxies(proxyUrl: string): void { + if (!this.bannedProxies.includes(proxyUrl)) { + this.bannedProxies.push(proxyUrl); + this.unbannedProxies = CORS_PROXIES.filter((proxy) => !this.bannedProxies.includes(proxy)); + } + } + + static getRandomUnbannedProxy(): string | undefined { + if (this.unbannedProxies.length === 0) { + //throw new Error("No unbanned proxies available"); + return undefined; + } + return this.unbannedProxies[Math.floor(Math.random() * this.unbannedProxies.length)]; + } + + static async request(url: string, config: RequestInit = {}, proxyRequest = true, requests = 0, customProxy: string | undefined = undefined): Promise { + try { + if (proxyRequest) { + const proxyUrl = customProxy ? customProxy + "/" : this.getRandomUnbannedProxy() != undefined ? `${this.getRandomUnbannedProxy()}/` : ""; + const modifyUrl = proxyUrl + url; + + const controller = new AbortController(); + const id = setTimeout(() => { + this.updateBannedProxies(proxyUrl); + controller.abort(); + }, 8000); + + try { + config = { + ...config, + headers: { + ...config.headers, + Origin: "https://anify.tv", + }, + }; + const response = await fetch(modifyUrl, { signal: controller.signal, ...config }).catch((err) => { + return { + ok: false, + status: 500, + statusText: "Timeout", + json: () => Promise.resolve({ error: err }), + } as Response; + }); + if (!response.ok) { + this.updateBannedProxies(proxyUrl); + } + + if (response.statusText === "Timeout") { + if (requests >= 3) { + console.log(colors.red("Request timed out. Retried 3 times. Aborting...")); + return response; + } + + return this.request(url, config, proxyRequest, requests + 1); + } + + clearTimeout(id); + return response; + } catch (error) { + console.log(proxyUrl); + clearTimeout(id); + throw error; + } + } else { + return fetch(url, config); + } + } catch (e) { + console.log(e); + return { + ok: false, + status: 500, + statusText: "Internal Server Error", + } as Response; + } + } +} diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 54ecdd3..80c1303 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -1,11 +1,11 @@ import dotenv from "dotenv"; dotenv.config(); -import { search } from "./database/impl/search"; -import { Type } from "./types/enums"; -import { init } from "./database"; -import { scrapeCorsProxies } from "./proxies/impl/scrapeProxies"; -import { checkCorsProxies } from "./proxies/impl/checkProxies"; import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; +import NineAnime from "./mappings/impl/anime/nineanime"; -fetchCorsProxies().then(console.log); +fetchCorsProxies().then(async (_) => { + const nineAnime = new NineAnime(); + const data = await nineAnime.search("Mushoku Tensei"); + console.log(data); +}); diff --git a/anify-backend-recode/src/lib/event.ts b/anify-backend-recode/src/lib/event.ts deleted file mode 100644 index f2c61a2..0000000 --- a/anify-backend-recode/src/lib/event.ts +++ /dev/null @@ -1,14 +0,0 @@ -import EventEmitter2 from "eventemitter2"; - -export enum Events { - COMPLETED_MAPPING_LOAD = "mapping.load.completed", - COMPLETED_SKIPTIMES_LOAD = "skiptimes.load.completed", - COMPLETED_SEARCH_LOAD = "search.load.completed", - COMPLETED_SEASONAL_LOAD = "seasonal.load.completed", - COMPLETED_ENTRY_CREATION = "entry.creation.completed", - COMPLETED_PAGE_UPLOAD = "page.upload.completed", -} - -const emitter = new EventEmitter2({}); - -export default emitter; diff --git a/anify-backend-recode/src/lib/impl/entry.ts b/anify-backend-recode/src/lib/impl/entry.ts index 473c294..cd6cc81 100644 --- a/anify-backend-recode/src/lib/impl/entry.ts +++ b/anify-backend-recode/src/lib/impl/entry.ts @@ -2,7 +2,7 @@ import { create } from "../../database/impl/create"; import { get } from "../../database/impl/get"; import { Type } from "../../types/enums"; import { Anime, Manga } from "../../types/types"; -import emitter, { Events } from "../event"; +import emitter, { Events } from "../"; export const createEntry = async (data: { toInsert: Anime | Manga; type: Type }) => { const existing = await get(String(data.toInsert.id)); diff --git a/anify-backend-recode/src/lib/index.ts b/anify-backend-recode/src/lib/index.ts index e69de29..f2c61a2 100644 --- a/anify-backend-recode/src/lib/index.ts +++ b/anify-backend-recode/src/lib/index.ts @@ -0,0 +1,14 @@ +import EventEmitter2 from "eventemitter2"; + +export enum Events { + COMPLETED_MAPPING_LOAD = "mapping.load.completed", + COMPLETED_SKIPTIMES_LOAD = "skiptimes.load.completed", + COMPLETED_SEARCH_LOAD = "search.load.completed", + COMPLETED_SEASONAL_LOAD = "seasonal.load.completed", + COMPLETED_ENTRY_CREATION = "entry.creation.completed", + COMPLETED_PAGE_UPLOAD = "page.upload.completed", +} + +const emitter = new EventEmitter2({}); + +export default emitter; diff --git a/anify-backend-recode/src/mappings/impl/anime/index.ts b/anify-backend-recode/src/mappings/impl/anime/index.ts new file mode 100644 index 0000000..62012e3 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/anime/index.ts @@ -0,0 +1,36 @@ +import Http from "../../../helper/request"; +import { Format, ProviderType, StreamingServers, SubType } from "../../../types/enums"; +import { Episode, Result, Server, Source } from "../../../types/types"; + +export default abstract class AnimeProvider { + abstract rateLimit: number; + abstract id: string; + abstract url: string; + abstract formats: Format[]; + + public providerType: ProviderType = ProviderType.ANIME; + public customProxy: string | undefined; + + async search(query: string, format?: Format, year?: number): Promise { + return undefined; + } + + async fetchEpisodes(id: string): Promise { + return undefined; + } + + async fetchSources(id: string, subType: SubType = SubType.SUB, server: StreamingServers): Promise { + return undefined; + } + + async fetchServers(id: string): Promise { + return undefined; + } + + async request(url: string, config: RequestInit = {}, proxyRequest = false): Promise { + return Http.request(url, config, proxyRequest, 0, this.customProxy); + } + + abstract get subTypes(): SubType[]; + abstract get headers(): Record | undefined; +} diff --git a/anify-backend-recode/src/mappings/impl/anime/nineanime.ts b/anify-backend-recode/src/mappings/impl/anime/nineanime.ts new file mode 100644 index 0000000..d6c7264 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/anime/nineanime.ts @@ -0,0 +1,349 @@ +import AnimeProvider from "."; +import { Episode, Result, Server, Source } from "../../../types/types"; +import { load } from "cheerio"; + +import { env } from "../../../env"; +import { Format, Formats, StreamingServers, SubType } from "../../../types/enums"; +import Extractor from "../../../helper/extractor"; + +export default class NineAnime extends AnimeProvider { + override rateLimit = 250; + override id = "9anime"; + override url = "https://aniwave.to"; + override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; + + private resolver: string | undefined = env.NINEANIME_RESOLVER; + private resolverKey: string | undefined = env.NINEANIME_KEY || `9anime`; + + override get subTypes(): SubType[] { + return [SubType.SUB, SubType.DUB]; + } + + override get headers(): Record | undefined { + return { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }; + } + + override async search(query: string, format?: Format, year?: number): Promise { + const vrf = await this.getSearchVRF(query); + const data = await (await this.request(`${this.url}/ajax/anime/search?keyword=${encodeURIComponent(query)}&${vrf.vrfQuery}=${encodeURIComponent(vrf.url)}`, {}, true)).json(); + + const $ = load(data.result.html); + + const results: Result[] = $("div.items > a.item") + .map((i, el) => { + const title = $(el).find("div.name"); + const altTitles: string[] = [title.attr("data-jp")!]; + + const year = parseInt($(el).find("div.info div.meta span.dot").last()?.text()?.trim()?.split(",")[1]) || 0; + + const formatString = $(el).find("div.info div.meta span.dot").eq(-2)?.text()?.trim(); + const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + return { + id: $(el).attr("href")!, + title: title.text().trim(), + altTitles, + year, + format, + img: $(el).find("img").attr("src")!, + providerId: this.id, + }; + }) + .get(); + + return results; + } + + override async fetchEpisodes(id: string): Promise { + const data = await (await this.request(`${this.url}${id}`, {})).text(); + + const $ = load(data); + + const nineId = $("#watch-main").attr("data-id")!; + + const vrf = await this.getVRF(nineId); + + const req = await this.request(`${this.url}/ajax/episode/list/${nineId}?${vrf.vrfQuery}=${encodeURIComponent(vrf.url)}`, {}, true); + + const $$ = load((await req.json()).result); + + const episodes: Episode[] = []; + + for (const el of $$("div.episodes > ul > li")) { + const liTitle = $(el).attr("title")?.split(" - ")?.[0]?.split("Release: ")[1] ?? new Date().toDateString(); + + const updatedAt = new Date(liTitle).getTime(); + + const episode: Episode = { + //id: ids[0], <- if i only want sub + id: $$(el).find("a").attr("data-ids")!, + number: parseInt($$(el).find("a").attr("data-num")?.toString()!), + title: $$(el).find("span").text()?.length > 0 ? $$(el).find("span").text() : "Episode " + $$(el).find("a").attr("data-num"), + isFiller: $$(el).find("a").hasClass("filler"), + img: null, + hasDub: $$(el).find("a").attr("data-dub")?.toString() === "1", + updatedAt, + }; + + episodes.push(episode); + } + + return episodes; + } + + override async fetchSources(id: string, subType: SubType = SubType.SUB, server: StreamingServers = StreamingServers.MyCloud): Promise { + const result: Source = { + sources: [], + subtitles: [], + audio: [], + intro: { + start: 0, + end: 0, + }, + outro: { + start: 0, + end: 0, + }, + headers: this.headers ?? {}, + }; + + if (id.startsWith("http")) { + const serverUrl = new URL(id); + + const req = await this.request(serverUrl.href, {}); + if (!req.ok) { + return result; + } + const json = await req.json(); + if (!json.result) { + return result; + } + + const serverID = serverUrl.href.split(`${this.url}/ajax/server/`)[1].split("?vrf")[0]; + const serverVrf = await this.getRawVRF(serverID); + + const serverSource = await (await this.request(`${this.url}/ajax/server/${serverID}?${serverVrf.vrfQuery}=${encodeURIComponent(serverVrf.url)}`, {}, true)).json(); + + try { + const skipData = JSON.parse((await this.decodeURL(json.result?.skip_data!)).url); + result.intro.start = skipData?.intro?.[0] ?? 0; + result.intro.end = skipData?.intro?.[1] ?? 0; + + result.outro.start = skipData?.outro?.[0] ?? 0; + result.outro.end = skipData?.outro?.[1] ?? 0; + } catch (e) { + console.error("9Anime skip data error"); + console.error(e); + } + + const source = (await (await this.request(`${this.resolver}/decrypt?query=${encodeURIComponent(serverSource.result?.url)}&apikey=${this.resolverKey}`)).json()).url.split("/").pop(); + + return await new Extractor(source, result).extract(server); + } + + if (subType === SubType.SUB) { + id = id.split(",")[0]; + } else { + id = id.split(",")[1]; + if (!id) return result; + } + + const servers = (await this.fetchServers(id))!; + + let s = servers.find((s) => s.name === server); + + switch (server) { + case StreamingServers.VizCloud: + s = servers.find((s) => s.name === "vidstream")!; + if (!s) throw new Error("Vidstream server found"); + break; + case StreamingServers.StreamTape: + s = servers.find((s) => s.name === "streamtape"); + if (!s) throw new Error("Streamtape server found"); + break; + case StreamingServers.MyCloud: + s = servers.find((s) => s.name === "mycloud"); + if (!s) throw new Error("Mycloud server found"); + break; + case StreamingServers.Filemoon: + s = servers.find((s) => s.name === "filemoon"); + if (!s) throw new Error("Filemoon server found"); + break; + default: + throw new Error("Server not found"); + } + + return await this.fetchSources(s.url, subType, server); + } + + override async fetchServers(id: string): Promise { + const vrf = await this.getVRF(id); + const url = `${this.url}/ajax/server/list/${id}?${vrf.vrfQuery}=${encodeURIComponent(vrf.url)}`; + + const data = await (await this.request(url, {}, true)).json(); + + const $ = load(data.result); + + const servers: Server[] = []; + const promises: Promise[] = []; + + $(".type > ul > li").each((i, el) => { + const promise: Promise = new Promise(async (resolve, reject) => { + const serverId = $(el).attr("data-link-id")!; + const vrf = await this.getRawVRF(serverId); + servers.push({ + name: $(el).text().toLocaleLowerCase(), + url: `${this.url}/ajax/server/${serverId}?${vrf.vrfQuery}=${encodeURIComponent(vrf.url)}`, + }); + resolve(true); + }); + promises.push(promise); + }); + + await Promise.all(promises); + return servers; + } + + private async getVRF(query: string): Promise { + if (!this.resolver) + return { + url: query, + vrfQuery: "vrf", + }; + + return await (await this.request(`${this.resolver}/vrf?query=${encodeURIComponent(query)}&apikey=${this.resolverKey}`, {})).json(); + } + + public async getSearchVRF(query: string): Promise { + if (!this.resolver) + return { + url: query, + vrfQuery: "vrf", + }; + + return await (await this.request(`${this.resolver}/9anime-search?query=${encodeURIComponent(query)}&apikey=${this.resolverKey}`, {})).json(); + } + + private async getRawVRF(query: string): Promise { + if (!this.resolver) + return { + url: query, + vrfQuery: "vrf", + }; + + return await (await this.request(`${this.resolver}/rawVrf?query=${encodeURIComponent(query)}&apikey=${this.resolverKey}`, {})).json(); + } + + private async decodeURL(query: string): Promise { + if (!this.resolver) + return { + url: query, + vrfQuery: "vrf", + }; + + return await (await this.request(`${this.resolver}/decrypt?query=${encodeURIComponent(query)}&apikey=${this.resolverKey}`, {})).json(); + } + + // This bypass works. However because it sends requests very quickly in a short amount of time, it causes proxies to get banned very quickly. + /* + override async request(url: string, options: RequestInit = {}, proxyRequest = true): Promise { + const proxy = proxyRequest ? ((this.customProxy?.length ?? 0) > 0 ? this.customProxy : Http.getRandomUnbannedProxy()) : undefined; + + const headers = { + "User-Agent": this.userAgent, + Referer: this.url, + }; + + const req1 = await Http.request(this.url, { headers }, proxyRequest, 0, proxy); + + const data1 = await req1.text(); + + if (!isString(data1)) { + return Http.request(url, options, proxyRequest, 0, proxy); + } + + // Extract _a and _b values + const _aMatch = data1.match(/var _a\s*=\s*'([0-9a-f]+)'/); + const _bMatch = data1.match(/_b\s*=\s*'([0-9a-f]+)'/); + const _a = _aMatch?.[1]; + const _b = _bMatch?.[1]; + if (!_a || !_b) { + return Http.request(url, options, proxyRequest, 0, proxy); + } + + // Now fetch k value + const req2 = await Http.request(`${this.url}/waf-js-run`, { headers }, proxyRequest, 0, proxy); + const data2 = await req2.text(); + + const context = { global: global, data: "" }; + vm.createContext(context); + + vm.runInContext( + ` + const location = { + href: "${this.url}/waf-js-run", + }; + + function EvalDecode(source) { + global._eval = global.eval; + + global.eval = (_code) => { + global.eval = global._eval; + return _code; + }; + + return global._eval(source); + } + + const code = EvalDecode("${data2}"); + data = code; + `, + context + ); + + const kMatch = context.data.match(/var k='([^']+)'/); + if (!kMatch) { + console.error("Failed to extract k value"); + return Http.request(url, options, proxyRequest, 0, proxy); + } + const k = kMatch[1]; + + // Construct o value + const l = k.length; + if (l !== _a.length || l !== _b.length) { + console.error("Length of k, _a and _b do not match"); + return Http.request(url, options, proxyRequest, 0, proxy); + } + const o = Array.from(k) + .map((char, i) => char + _a[i] + _b[i]) + .join(""); + + // Update URL with __jscheck parameter + const updatedUrl = this.url.replace(/&?__jscheck=[^&]+/g, "") + (this.url.indexOf("?") < 0 ? "?" : "&") + "__jscheck=" + o; + + const req3 = await Http.request(updatedUrl, { headers }, proxyRequest, 0, proxy); + const cookies = req3.headers["set-cookie"]; + + return Http.request(url, { headers: { Cookie: cookies?.join("; ") ?? "" }, ...options }, proxyRequest, 0, proxy); + } + */ + + /* + The waf page evals this: + (function (h) { + var k = 'c419b06b4c6579b50ff05adb3b8424f1', + l = k.length, + u = 'undefined', + i, o = ''; + if (typeof _a == u || typeof _b == u) return; + if (l != _a.length || l != _b.length) return; + for (i = 0; i < l; i++) o += k[i] + _a[i] + _b[i]; + location.href = h.replace(/&?__jscheck=[^&]+/g, '') + (h.indexOf('?') < 0 ? '?' : '&') + '__jscheck=' + o; + })(location.href); + */ +} + +type VRF = { + url: string; + vrfQuery: string; +}; diff --git a/anify-backend-recode/src/proxies/index.ts b/anify-backend-recode/src/proxies/index.ts index 4d340ec..9779e6f 100644 --- a/anify-backend-recode/src/proxies/index.ts +++ b/anify-backend-recode/src/proxies/index.ts @@ -2,16 +2,6 @@ * @description Handles the scraping of CORS proxies. */ -import colors from "colors"; -import { existsSync, writeFileSync } from "fs"; -import { readFile, writeFile } from "fs/promises"; -import { join } from "path"; -import ChunkedExecutor from "./executor"; -import { isString } from "../helper"; -import { ANIME_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS } from "../mappings"; -import { env } from "bun"; - // List of CORS proxies export const CORS_PROXIES: string[] = []; - export const toCheck: string[] = []; diff --git a/anify-backend-recode/src/types/enums.ts b/anify-backend-recode/src/types/enums.ts index 8c9e4e0..370f45a 100644 --- a/anify-backend-recode/src/types/enums.ts +++ b/anify-backend-recode/src/types/enums.ts @@ -24,6 +24,8 @@ export const enum Format { UNKNOWN = "UNKNOWN", } +export const Formats = [Format.TV, Format.TV_SHORT, Format.MOVIE, Format.SPECIAL, Format.OVA, Format.ONA, Format.MUSIC, Format.MANGA, Format.NOVEL, Format.ONE_SHOT, Format.UNKNOWN]; + export const enum Season { WINTER = "WINTER", SPRING = "SPRING", From becdb54e0d3d04c5740afed50e0bb4d54c7b1a41 Mon Sep 17 00:00:00 2001 From: Eltik Date: Tue, 5 Sep 2023 18:31:51 -0400 Subject: [PATCH 04/77] Add mappings code --- .../src/helper/stringSimilarity.ts | 159 +++++++ anify-backend-recode/src/helper/title.ts | 105 +++++ anify-backend-recode/src/index.ts | 5 +- anify-backend-recode/src/lib/impl/mappings.ts | 439 ++++++++++++++++++ .../src/mappings/impl/anime/animepahe.ts | 171 +++++++ .../src/mappings/impl/information/index.ts | 47 ++ .../src/mappings/impl/manga/index.ts | 47 ++ .../src/mappings/impl/meta/index.ts | 21 + anify-backend-recode/src/mappings/index.ts | 48 +- anify-backend-recode/src/types/types.ts | 16 + 10 files changed, 1050 insertions(+), 8 deletions(-) create mode 100644 anify-backend-recode/src/helper/stringSimilarity.ts create mode 100644 anify-backend-recode/src/helper/title.ts create mode 100644 anify-backend-recode/src/lib/impl/mappings.ts create mode 100644 anify-backend-recode/src/mappings/impl/anime/animepahe.ts create mode 100644 anify-backend-recode/src/mappings/impl/information/index.ts create mode 100644 anify-backend-recode/src/mappings/impl/manga/index.ts create mode 100644 anify-backend-recode/src/mappings/impl/meta/index.ts diff --git a/anify-backend-recode/src/helper/stringSimilarity.ts b/anify-backend-recode/src/helper/stringSimilarity.ts new file mode 100644 index 0000000..81bc234 --- /dev/null +++ b/anify-backend-recode/src/helper/stringSimilarity.ts @@ -0,0 +1,159 @@ +import { clean, sanitizeTitle } from "./title"; + +export function similarity(externalTitle: string, title: string, titleArray: string[] = []): { same: boolean; value: number } { + if (!title) { + title = ""; + } + let simi = compareTwoStrings(sanitizeTitle(title.toLowerCase()), externalTitle.toLowerCase()); + titleArray.forEach((el) => { + if (el) { + const tempSimi = compareTwoStrings(title.toLowerCase(), el.toLowerCase()); + if (tempSimi > simi) simi = tempSimi; + } + }); + let found = false; + if (simi > 0.6) { + found = true; + } + + return { + same: found, + value: simi, + }; +} + +// From npm package string-similarity +export function compareTwoStrings(first: string, second: string): number { + first = first.replace(/\s+/g, ""); + second = second.replace(/\s+/g, ""); + + if (first === second) return 1; // identical or empty + if (first.length < 2 || second.length < 2) return 0; // if either is a 0-letter or 1-letter string + + const firstBigrams = new Map(); + for (let i = 0; i < first.length - 1; i++) { + const bigram = first.substring(i, i + 2); + const count = firstBigrams.has(bigram) ? firstBigrams.get(bigram) + 1 : 1; + + firstBigrams.set(bigram, count); + } + + let intersectionSize = 0; + for (let i = 0; i < second.length - 1; i++) { + const bigram = second.substring(i, i + 2); + const count = firstBigrams.has(bigram) ? firstBigrams.get(bigram) : 0; + + if (count > 0) { + firstBigrams.set(bigram, count - 1); + intersectionSize++; + } + } + + return (2.0 * intersectionSize) / (first.length + second.length - 2); +} + +export function findBestMatch(mainString: string, targetStrings: string[]): StringResult { + if (!areArgsValid(mainString, targetStrings)) { + throw new Error("Bad arguments: First argument should be a string, second should be an array of strings"); + } + + const ratings: { target: string; rating: number }[] = []; + let bestMatchIndex = 0; + + for (let i = 0; i < targetStrings.length; i++) { + const currentTargetString: string = targetStrings[i]; + const currentRating: number = compareTwoStrings(mainString, currentTargetString); + ratings.push({ target: currentTargetString, rating: currentRating }); + if (currentRating > ratings[bestMatchIndex].rating) { + bestMatchIndex = i; + } + } + + const bestMatch = ratings[bestMatchIndex]; + + return { ratings: ratings, bestMatch: bestMatch, bestMatchIndex: bestMatchIndex }; +} + +export function findBestMatchArray(mainStrings: string[], targetStrings: string[]): StringResult { + const mainStringResults: StringResult[] = []; + + mainStrings.forEach((mainString) => { + const ratings: { target: string; rating: number; main: string }[] = []; + let bestMatchIndex = 0; + + for (let i = 0; i < targetStrings.length; i++) { + const currentTargetString: string = targetStrings[i]; + const currentRating: number = compareTwoStrings(mainString, currentTargetString); + ratings.push({ target: currentTargetString, rating: currentRating, main: mainString }); + + if (currentRating > ratings[bestMatchIndex].rating) { + bestMatchIndex = i; + } + } + + mainStringResults.push({ + ratings: ratings, + bestMatch: ratings[bestMatchIndex], + bestMatchIndex: bestMatchIndex, + }); + }); + + let overallBestMatchIndex = 0; + for (let i = 1; i < mainStringResults.length; i++) { + if (mainStringResults[i].bestMatch.rating > mainStringResults[overallBestMatchIndex].bestMatch.rating) { + overallBestMatchIndex = i; + } + } + + return mainStringResults[overallBestMatchIndex]; +} + +export function findBestMatch2DArray(mainStrings: string[], targetStrings: string[][]): StringResult { + let overallBestMatch: StringResult = { + ratings: [], + bestMatch: { target: "", rating: 0 }, + bestMatchIndex: 0, + }; + + mainStrings.forEach((mainString) => { + targetStrings.forEach((targetArray, targetArrayIndex) => { + const ratings: Array<{ target: string; rating: number }> = []; + + targetArray.forEach((targetString) => { + const currentRating = compareTwoStrings(clean(mainString.toLowerCase().trim()), clean(targetString).toLowerCase().trim()); + + ratings.push({ target: targetString, rating: currentRating }); + }); + + const bestMatchIndex = ratings.reduce((bestIndex, x, i, arr) => (x.rating > arr[bestIndex].rating ? i : bestIndex), 0); + + if (ratings[bestMatchIndex].rating > overallBestMatch.bestMatch.rating) { + overallBestMatch = { + ratings, + bestMatch: ratings[bestMatchIndex], + bestMatchIndex: targetArrayIndex, + }; + } + }); + }); + + return overallBestMatch; +} +function areArgsValid(mainString: string, targetStrings: string[]): boolean { + if (typeof mainString !== "string") return false; + if (!Array.isArray(targetStrings)) return false; + if (!targetStrings.length) return false; + if ( + targetStrings.find(function (s) { + return typeof s !== "string"; + }) + ) + return false; + return true; +} + +interface StringResult { + ratings: Array<{ target: string; rating: number }>; + bestMatch: { target: string; rating: number }; + bestMatchIndex: number; +} diff --git a/anify-backend-recode/src/helper/title.ts b/anify-backend-recode/src/helper/title.ts new file mode 100644 index 0000000..c5f69a9 --- /dev/null +++ b/anify-backend-recode/src/helper/title.ts @@ -0,0 +1,105 @@ +export function clean(title: string) { + return transformSpecificVariations( + removeSpecialChars( + title + ?.replaceAll(/[^A-Za-z0-9!@#$%^&*() ]/gim, " ") + .replaceAll(/(th|rd|nd|st) (Season|season)/gim, "") + .replaceAll(/\([^\(]*\)$/gim, "") + .replaceAll("season", "") + .replaceAll(" ", " ") + .replaceAll('"', "") + .trimEnd(), + ), + ); +} + +export function removeSpecialChars(title: string) { + return title + ?.replaceAll(/[^A-Za-z0-9!@#$%^&*()\-= ]/gim, " ") + .replaceAll(/[^A-Za-z0-9\-= ]/gim, "") + .replaceAll(" ", " "); +} + +export function transformSpecificVariations(title: string) { + return title?.replaceAll("yuu", "yu").replaceAll(" ou", " oh"); +} + +export function sanitizeTitle(title: string): string { + let resTitle = title.replace(/ *(\(dub\)|\(sub\)|\(uncensored\)|\(uncut\)|\(subbed\)|\(dubbed\))/i, ""); + resTitle = resTitle.replace(/ *\([^)]+audio\)/i, ""); + resTitle = resTitle.replace(/ BD( |$)/i, ""); + resTitle = resTitle.replace(/\(TV\)/g, ""); + resTitle = resTitle.trim(); + resTitle = resTitle.substring(0, 99); // truncate + return resTitle; +} + +export const slugify = (...args: (string | number)[]): string => { + const defaultReplacements = [ + ["[aàáâãäåāăąǻάαа]", "a"], + ["[bбḃ]", "b"], + ["[cçćĉċčћ]", "c"], + ["[dðďđδдђḋ]", "d"], + ["[eèéêëēĕėęěέεеэѐё]", "e"], + ["[fƒφфḟ]", "f"], + ["[gĝğġģγгѓґ]", "g"], + ["[hĥħ]", "h"], + ["[iìíîïĩīĭįıΐήίηιϊийіїѝ]", "i"], + ["[jĵј]", "j"], + ["[kķĸκкќ]", "k"], + ["[lĺļľŀłλл]", "l"], + ["[mμмṁ]", "m"], + ["[nñńņňʼnŋνн]", "n"], + ["[oòóôõöōŏőοωόώо]", "o"], + ["[pπпṗ]", "p"], + ["q", "q"], + ["[rŕŗřρр]", "r"], + ["[sśŝşšſșςσсṡ]", "s"], + ["[tţťŧțτтṫ]", "t"], + ["[uùúûüũūŭůűųуў]", "u"], + ["[vβв]", "v"], + ["[wŵẁẃẅ]", "w"], + ["[xξ]", "x"], + ["[yýÿŷΰυϋύыỳ]", "y"], + ["[zźżžζз]", "z"], + ["[æǽ]", "ae"], + ["[χч]", "ch"], + ["[ѕџ]", "dz"], + ["fi", "fi"], + ["fl", "fl"], + ["я", "ia"], + ["[ъє]", "ie"], + ["ij", "ij"], + ["ю", "iu"], + ["х", "kh"], + ["љ", "lj"], + ["њ", "nj"], + ["[øœǿ]", "oe"], + ["ψ", "ps"], + ["ш", "sh"], + ["щ", "shch"], + ["ß", "ss"], + ["[þθ]", "th"], + ["ц", "ts"], + ["ж", "zh"], + + // White_Space, General_Category=Dash_Punctuation and Control Codes + ["[\\u0009-\\u000D\\u001C-\\u001F\\u0020\\u002D\\u0085\\u00A0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000\\u058A\\u05BE\\u1400\\u1806\\u2010-\\u2015\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D]", "-"], + ]; + + const replaceLoweringCase = (string: string, [regExp, replacement]: any) => string.replace(RegExp(regExp, "giu"), replacement); + + let value = args.join(" "); + + defaultReplacements.forEach(([a, b]) => { + value = replaceLoweringCase(value, [a, b]); + }); + + return value + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "-") + .toLowerCase() + .trim() + .replace(/[^a-z0-9 ]/g, "-") + .replace(/\s+/g, "-"); +}; diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 80c1303..8bb35f6 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -2,10 +2,9 @@ import dotenv from "dotenv"; dotenv.config(); import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; -import NineAnime from "./mappings/impl/anime/nineanime"; +import { animeProviders } from "./mappings"; fetchCorsProxies().then(async (_) => { - const nineAnime = new NineAnime(); - const data = await nineAnime.search("Mushoku Tensei"); + const data = await animeProviders["9anime"].search("Mushoku Tensei"); console.log(data); }); diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend-recode/src/lib/impl/mappings.ts new file mode 100644 index 0000000..6d77aee --- /dev/null +++ b/anify-backend-recode/src/lib/impl/mappings.ts @@ -0,0 +1,439 @@ +import colors from "colors"; +import { get } from "../../database/impl/get"; +import emitter, { Events } from ".."; +import { Anime, AnimeInfo, Manga, MangaInfo, Result } from "../../types/types"; +import { Format, MediaStatus, ProviderType, Season, Type } from "../../types/enums"; +import { ANIME_PROVIDERS, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, animeProviders, infoProviders, mangaProviders, metaProviders } from "../../mappings"; +import { clean, slugify } from "../../helper/title"; +import { findBestMatch2DArray, similarity } from "../../helper/stringSimilarity"; +import { isString } from "../../helper"; +import InformationProvider from "../../mappings/impl/information"; + +export const loadMapping = async (data: { id: string; type: Type }, aniData?: AnimeInfo | MangaInfo | null, retries = 0, media?: Anime | Manga): Promise => { + const MIN_MAPPINGS = 3; + const MAX_RETRIES = 2; + + if (retries > 0) console.log(colors.yellow("Remapping ") + colors.blue(data.id) + colors.yellow(" with retry ") + colors.blue(retries + "") + colors.yellow("...")); + + if (!aniData) { + try { + // First check if exists in database + const existing = await get(data.id); + + if (existing) { + // If it does, emit the event and return + await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, [existing]); + return [existing] as Anime[] | Manga[]; + } + } catch (e) { + console.error(e); + console.log(colors.red("Error while fetching from database.")); + } + } + + console.log(colors.gray("Loading mapping for ") + colors.blue(data.id) + colors.gray("...")); + + // Map only one media + if (!aniData) { + aniData = await (infoProviders.anilist as any).getMedia(data.id); + } + + if (!aniData) { + await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, []); + return []; + } + + if ((aniData as any).isAdult) { + console.log(colors.red("Media is adult. Skipping...")); + return []; + } + if (aniData.status === MediaStatus.NOT_YET_RELEASED) { + console.log(colors.red("Media is not yet released. Skipping...")); + return []; + } + + const result = await map((aniData as any)?.type, [aniData?.format!], aniData, media); + + // Only return if the ID matches the one we're looking for + // If it isn't, we don't want to return. + for (let i = 0; i < result.length; i++) { + if (String(result[i].id) === String(data.id)) { + console.log(colors.gray("Found mapping for ") + colors.blue(data.id) + colors.gray(".") + colors.gray(" Saving...")); + await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, [result[i]]); + + // Only return if anime or manga mappings are greater than MIN_MAPPINGS. + const mappings = result[i].mappings.filter((item) => item.providerType === ProviderType.ANIME || item.providerType === ProviderType.MANGA); + + if (mappings.length < MIN_MAPPINGS && retries < MAX_RETRIES) return loadMapping(data, aniData, retries + 1, result[i]); + + return [result[i]] as Anime[] | Manga[]; + } + } + + await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, []); + return []; +}; + +// Map and insert a mapping into the database +export const insertMapping = async (data: { id: string; type: Type }, aniData: AnimeInfo | MangaInfo | undefined) => { + if ((aniData as any).isAdult) return []; + + const result = await map((aniData as any)?.type, [aniData?.format!], aniData); + + // Only return if the ID matches the one we're looking for + // If it isn't, we don't want to return. + for (let i = 0; i < result.length; i++) { + if (String(result[i].id) === String(data.id)) { + console.log(colors.gray("Found mapping for ") + colors.blue(data.id) + colors.gray(".") + colors.gray(" Saving...")); + await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, [result[i]]); + return [result[i]]; + } + } + + await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, []); + return []; +}; + +// Map a media to AniList +export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | MangaInfo | undefined, media?: Anime | Manga): Promise => { + const providers = type === Type.ANIME ? ANIME_PROVIDERS : MANGA_PROVIDERS; + providers.push(...(META_PROVIDERS as any)); + + if (media) { + aniData?.synonyms?.push(...media.synonyms); + aniData?.synonyms?.push(...(media.title.english ? [media.title.english] : [])); + aniData?.synonyms?.push(...(media.title.native ? [media.title.native] : [])); + aniData?.synonyms?.push(...(media.title.romaji ? [media.title.romaji] : [])); + + if (aniData) { + aniData.title.english = media.title.english; + aniData.title.native = media.title.native; + aniData.title.romaji = media.title.romaji; + + aniData.format = media.format; + } + } + + // Filter out providers that don't contain the format + const suitableProviders = providers + .filter((provider) => { + if (formats && provider.formats) { + return formats.some((format) => provider.formats.includes(format)); + } + return true; + }) + .reduce((acc: any[], currentProvider) => { + const existingProvider = acc.find((provider: any) => provider.id === currentProvider.id); + if (!existingProvider) { + acc.push(currentProvider); + } + return acc; + }, []); + + // Search for the media on each provider + const promises = suitableProviders.map((provider: any) => { + const search = [provider.search(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native, aniData?.format, (aniData as any)?.year)]; + return Promise.all(search) + .then((results) => { + return results.find((r) => r?.length !== 0) || []; + }) + .catch((err) => { + console.log(colors.red("Error fetching from provider ") + colors.blue(provider.id) + colors.red(".")); + console.error(err); + return []; + }); + }); + + const resultsArray = await Promise.all(promises); + + const mappings: MappedResult[] = []; + + // Loop through each provider and find the best match + for (let i = 0; i < resultsArray.length; i++) { + const providerData = resultsArray[i]; + const title: string = (aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native)!; + + const providerTitles = providerData.map((m: Result) => { + const titles = [m.title, ...(m.altTitles ?? [])]; + return titles; + }); + + // If there are no results, skip + if (providerTitles.length === 0) { + console.log(colors.gray("No results found for ") + colors.blue(title) + colors.gray(" on ") + colors.blue(suitableProviders[i].id) + colors.gray(".")); + continue; + } + + const titles = [aniData?.title.english, aniData?.title.romaji, aniData?.title.native].filter(isString); + const cleanedTitles = titles.map((x) => clean(x?.toLowerCase().trim() ?? "")); + + const bestMatchIndex = findBestMatch2DArray(cleanedTitles, providerTitles); + + if (bestMatchIndex.bestMatch.rating < 0.5) { + continue; + } + + const best: Result = providerData[bestMatchIndex.bestMatchIndex]; + + // Add checks + if (best.format != Format.UNKNOWN && (aniData as any)?.format && (aniData as any)?.format != Format.UNKNOWN && best.format != aniData?.format) continue; + if (best.year != 0 && (aniData as any)?.year && (aniData as any)?.year != 0 && best.year != (aniData as any)?.year) continue; + + const altTitles: any[] = Object.values((aniData as any)?.title).concat(aniData?.synonyms); + + const sim = similarity(title, best.title, altTitles); + + //if (sim.value < 0.6) continue; + if (mappings.filter((m) => m.data.id === best.id).length > 0) continue; + + mappings.push({ + id: (aniData as any).id, + slug: slugify(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native ?? ""), + data: best, + similarity: sim.value, + }); + } + + // Create the media object + const result = await createMedia(mappings, type); + + console.log(colors.yellow("Finished fetching from providers.") + colors.blue(" - ") + colors.yellow(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native!)); + return result; +}; + +export async function createMedia(mappings: MappedResult[], type: Type): Promise { + const results: any[] = []; + + for (const mapping of mappings) { + let hasPushed = false; + const providerType: ProviderType | null = animeProviders[mapping.data.providerId]?.providerType ? ProviderType.ANIME : mangaProviders[mapping.data.providerId]?.providerType ? ProviderType.MANGA : metaProviders[mapping.data.providerId]?.providerType ? ProviderType.META : infoProviders[mapping.data.providerId]?.providerType ? ProviderType.INFORMATION : null; + + for (const result of results) { + if (result.id === mapping.id) { + hasPushed = true; + + const toPush = { + id: mapping.data.id, + providerId: mapping.data.providerId, + providerType, + similarity: mapping.similarity, + }; + + result.mappings.push(toPush); + } + } + + if (!hasPushed) { + if (type === Type.ANIME) { + const anime: Anime = { + id: mapping.id, + slug: mapping.slug, + coverImage: "", + bannerImage: "", + trailer: "", + status: null, + type: Type.ANIME, + season: Season.UNKNOWN, + title: { + romaji: null, + english: null, + native: null, + }, + currentEpisode: null, + mappings: [ + { + id: mapping.data.id, + providerId: mapping.data.providerId, + providerType, + similarity: mapping.similarity, + }, + ], + synonyms: [], + countryOfOrigin: null, + description: null, + duration: null, + color: null, + year: null, + rating: { + anilist: 0, + mal: 0, + kitsu: 0, + }, + popularity: { + anilist: 0, + mal: 0, + kitsu: 0, + }, + genres: [], + format: Format.UNKNOWN, + relations: [], + totalEpisodes: 0, + episodes: { + latest: { + updatedAt: new Date(Date.now()).getTime(), + latestEpisode: 0, + latestTitle: "", + }, + data: [], + }, + tags: [], + artwork: [], + characters: [], + }; + + results.push(anime); + } else { + const manga: Manga = { + id: mapping.id, + slug: mapping.slug, + coverImage: "", + bannerImage: "", + status: null, + type: Type.MANGA, + title: { + romaji: null, + english: null, + native: null, + }, + mappings: [ + { + id: mapping.data.id, + providerId: mapping.data.providerId, + providerType, + similarity: mapping.similarity, + }, + ], + synonyms: [], + countryOfOrigin: null, + description: null, + color: null, + year: null, + rating: { + anilist: 0, + mal: 0, + kitsu: 0, + }, + popularity: { + anilist: 0, + mal: 0, + kitsu: 0, + }, + genres: [], + format: Format.UNKNOWN, + relations: [], + totalChapters: 0, + totalVolumes: 0, + chapters: { + latest: { + updatedAt: new Date(Date.now()).getTime(), + latestChapter: 0, + latestTitle: "", + }, + data: [], + }, + tags: [], + artwork: [], + characters: [], + }; + + results.push(manga); + } + } + } + + for (let i = 0; i < results.length; i++) { + const media = results[i]; + + for (let j = 0; j < INFORMATION_PROVIDERS.length; j++) { + const provider = INFORMATION_PROVIDERS[j]; + // Fetch info baesd on the media + const info = await provider.info(media).catch((err) => { + console.log(colors.red(`Error while fetching info for ${media.id} from ${provider.id}`)); + console.error(err); + return null; + }); + + if (!info) { + continue; + } + + // Fill the media object with all necessary info + fillMediaInfo(media, info, provider); + } + } + + return results; +} + +function fillMediaInfo(media: T, info: U, provider: InformationProvider): T { + try { + // Fields that need to be cross loaded. For example, rating which contains Kitsu, AniList, and MAL fields. + const crossLoadFields: (keyof AnimeInfo | MangaInfo)[] = ["popularity", "rating"]; + + // TODO: Comment needs to be written here + const specialLoadFields: (keyof AnimeInfo | MangaInfo)[] = ["title"]; + + for (const ak of Object.keys(info)) { + if (crossLoadFields.includes(ak as any) || provider.sharedArea.includes(ak as any) || specialLoadFields.includes(ak as any)) continue; + + const v = media[ak as keyof (Anime | Manga)]; + + let write = false; + if ((!v || v === "UNKNOWN") && !!info[ak as keyof (AnimeInfo | MangaInfo)] && info[ak as keyof (AnimeInfo | MangaInfo)] !== "UNKNOWN") { + write = true; + } else { + if (provider.priorityArea.includes(ak as any) && !!info[ak as keyof (AnimeInfo | MangaInfo)]) write = true; + } + + if (write) { + // Use type assertion to indicate that ak is of type keyof (Anime | Manga) + (media[ak as keyof (Anime | Manga)] as any) = info[ak as keyof (AnimeInfo | MangaInfo)] as any; + } + } + + for (const special of specialLoadFields) { + const v = info[special as keyof (AnimeInfo | MangaInfo)]; + + if (v) { + for (const [ak, av] of Object.entries(v)) { + if (av && (av as any)?.length) { + if (media[special as keyof (Anime | Manga)] !== null) { + (media[special as keyof (Anime | Manga)] as any)[ak] = av; + } + } + } + } + } + + for (const shared of provider.sharedArea) { + if (!media[shared as keyof (Anime | Manga)]) { + (media[shared as keyof (Anime | Manga)] as any) = []; + } + + (media[shared as keyof (Anime | Manga)] as any) = [...new Set((media[shared as keyof (Anime | Manga)] as any).concat(info[shared as keyof (AnimeInfo | MangaInfo)] ?? []))]; + } + + for (const crossLoad of crossLoadFields) { + if (info[crossLoad as keyof (AnimeInfo | MangaInfo)]) { + if (media[crossLoad as keyof (Anime | Manga)] !== null && media[crossLoad as keyof (Anime | Manga)] !== undefined) { + if (media[crossLoad as keyof (Anime | Manga)]) { + (media[crossLoad as keyof (Anime | Manga)] as any)[provider.id] = info[crossLoad as keyof (AnimeInfo | MangaInfo)] as any; + } + } + } + } + + return media; + } catch (e) { + console.log(colors.red(`Error while filling media info for ${media.id} with provider ${provider.id}`)); + console.error(e); + return media; + } +} + +export interface MappedResult { + id: string; + slug: string; + data: Result; + similarity: number; +} diff --git a/anify-backend-recode/src/mappings/impl/anime/animepahe.ts b/anify-backend-recode/src/mappings/impl/anime/animepahe.ts new file mode 100644 index 0000000..775d3a7 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/anime/animepahe.ts @@ -0,0 +1,171 @@ +import AnimeProvider from "."; +import { load } from "cheerio"; +import Extractor from "../../../helper/extractor"; +import { Format, Formats, StreamingServers, SubType } from "../../../types/enums"; +import { Episode, Result, Source } from "../../../types/types"; + +export default class AnimePahe extends AnimeProvider { + override rateLimit = 250; + override id = "animepahe"; + override url = "https://animepahe.com"; + + override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; + + override get subTypes(): SubType[] { + return [SubType.SUB]; + } + + override get headers(): Record | undefined { + return { Referer: "https://kwik.cx" }; + } + + override async search(query: string, format?: Format, year?: number): Promise { + const request = await this.request(`${this.url}/api?m=search&q=${encodeURIComponent(query)}`); + if (!request.ok) { + return []; + } + const data = await request.json(); + const results: Result[] = []; + + if (!data?.data) { + return []; + } + + data.data.map((item: { id: number; title: string; year: number; poster: string; type: string; session: string }) => { + const formatString: string = item.type.toUpperCase(); + const f: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + results.push({ + id: String(item.id) ?? item.session, + title: item.title, + year: item.year, + img: item.poster, + format: f, + altTitles: [], + providerId: this.id, + }); + }); + + return results; + } + + override async fetchEpisodes(id: string): Promise { + const episodes: Episode[] = []; + + const req = await (await this.request(`${this.url}${id.includes("-") ? `/anime/${id}` : `/a/${id}`}`)).text(); + + const $ = load(req); + + const tempId = $("head > meta[property='og:url']").attr("content")!.split("/").pop()!; + const { last_page, data } = await (await this.request(`${this.url}/api?m=release&id=${tempId}&sort=episode_asc&page=1`)).json(); + + data.map((item: { id: number; episode: number; title: string; snapshot: string; filler: number; created_at?: string }) => { + const updatedAt = new Date(item.created_at ?? Date.now()).getTime(); + + episodes.push({ + id: item.id + "-" + id, + number: item.episode, + title: item.title && item.title.length > 0 ? item.title : "Episode " + item.episode, + img: item.snapshot, + isFiller: item.filler === 1, + hasDub: false, + updatedAt, + }); + }); + + const pageNumbers = Array.from({ length: last_page - 1 }, (_, i) => i + 2); + + const promises = pageNumbers.map((pageNumber) => this.request(`${this.url}/api?m=release&id=${tempId}&sort=episode_asc&page=${pageNumber}`).then((res) => res.json())); + const results = await Promise.all(promises); + + results.forEach((showData) => { + for (const data of showData.data) { + if (data) { + const updatedAt = new Date(data.created_at ?? Date.now()).getTime(); + + episodes.push({ + id: data.id + "-" + id, + number: data.episode, + title: data.title && data.title.length > 0 ? data.title : "Episode " + data.episode, + img: data.snapshot, + isFiller: data.filler === 1, + hasDub: false, + updatedAt, + }); + } + } + }); + (data as any[]).sort((a, b) => a.number - b.number); + return episodes; + } + + override async fetchSources(id: string, subType: SubType = SubType.SUB, server: StreamingServers = StreamingServers.Kwik): Promise { + const animeId = id.split("-").pop()!; + const episodeId = id.split("-")[0]; + + const req = await this.request(`${this.url}${animeId.includes("-") ? `/anime/${animeId}` : `/a/${animeId}`}`); + + try { + const url = req.url; + // Need session id to fetch the watch page + const sessionId = url.split("/anime/").pop()!; + + const $ = load(await req.text()); + const tempId = $("head > meta[property='og:url']").attr("content")!.split("/").pop()!; + const { last_page, data } = await (await this.request(`${this.url}/api?m=release&id=${tempId}&sort=episode_asc&page=1`)).json(); + + let episodeSession = ""; + + for (let i = 0; i < data.length; i++) { + if (String(data[i].id) === episodeId) { + episodeSession = data[i].session; + break; + } + } + + if (episodeSession === "") { + for (let i = 1; i < last_page; i++) { + const data = await (await this.request(`${this.url}/api?m=release&id=${tempId}&sort=episode_asc&page=${i + 1}`)).json(); + + for (let j = 0; j < data.length; j++) { + if (String(data[j].id) === episodeId) { + episodeSession = data[j].session; + break; + } + } + + if (episodeSession !== "") break; + } + } + + if (episodeSession === "") return undefined; + + const watchReq = await (await this.request(`${this.url}/play/${sessionId}/${episodeSession}`)).text(); + + const regex = /https:\/\/kwik\.cx\/e\/\w+/g; + const matches = watchReq.match(regex); + + if (matches === null) return undefined; + + const result: Source = { + sources: [], + subtitles: [], + audio: [], + intro: { + start: 0, + end: 0, + }, + outro: { + start: 0, + end: 0, + }, + headers: this.headers ?? {}, + }; + + return await new Extractor(matches[0], result).extract(server); + } catch (e) { + console.error(e); + return undefined; + } + } +} diff --git a/anify-backend-recode/src/mappings/impl/information/index.ts b/anify-backend-recode/src/mappings/impl/information/index.ts new file mode 100644 index 0000000..c03c0c7 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/information/index.ts @@ -0,0 +1,47 @@ +import Http from "../../../helper/request"; +import { Format, ProviderType, Type } from "../../../types/enums"; +import { Anime, Manga } from "../../../types/types"; + +export default abstract class InformationProvider { + abstract id: string; + abstract url: string; + + public providerType: ProviderType = ProviderType.INFORMATION; + public customProxy: string | undefined; + + async search(query: string, type: Type, formats: Format[]): Promise { + return []; + } + + async info(media: T): Promise { + return undefined; + } + + get priorityArea(): MediaInfoKeys[] { + return []; + } + + get sharedArea(): MediaInfoKeys[] { + return []; + } + + async request(url: string, config: RequestInit = {}, proxyRequest = true): Promise { + return Http.request(url, config, proxyRequest, 0, this.customProxy); + } +} + +export type AnimeInfo = Pick & { + rating: number | null; + popularity: number | null; +}; + +export type MangaInfo = Pick & { + rating: number | null; + popularity: number | null; +}; + +type SharedKeys = { + [K in keyof T]: K extends keyof U ? K : never; +}[keyof T]; + +export type MediaInfoKeys = SharedKeys; diff --git a/anify-backend-recode/src/mappings/impl/manga/index.ts b/anify-backend-recode/src/mappings/impl/manga/index.ts new file mode 100644 index 0000000..d9af44c --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/manga/index.ts @@ -0,0 +1,47 @@ +import Http from "../../../helper/request"; +import { Format, ProviderType } from "../../../types/enums"; +import { Chapter, Page, Result } from "../../../types/types"; + +export default abstract class MangaProvider { + abstract rateLimit: number; + abstract id: string; + abstract url: string; + abstract formats: Format[]; + + public providerType: ProviderType = ProviderType.MANGA; + public customProxy: string | undefined; + + async search(query: string, format?: Format, year?: number): Promise { + return undefined; + } + + async fetchChapters(id: string): Promise { + return undefined; + } + + async fetchPages(id: string): Promise { + return undefined; + } + + async request(url: string, config: RequestInit = {}, proxyRequest = false): Promise { + return Http.request(url, config, proxyRequest, 0, this.customProxy); + } + + padNum(number: string, places: number): string { + // Credit to https://stackoverflow.com/a/10073788 + /* + * '17' + * '17.5' + * '17-17.5' + * '17 - 17.5' + * '17-123456789' + */ + let range = number.split("-"); + range = range.map((chapter) => { + chapter = chapter.trim(); + const digits = chapter.split(".")[0].length; + return "0".repeat(Math.max(0, places - digits)) + chapter; + }); + return range.join("-"); + } +} diff --git a/anify-backend-recode/src/mappings/impl/meta/index.ts b/anify-backend-recode/src/mappings/impl/meta/index.ts new file mode 100644 index 0000000..f62924a --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/meta/index.ts @@ -0,0 +1,21 @@ +import Http from "../../../helper/request"; +import { Format, ProviderType } from "../../../types/enums"; +import { Result } from "../../../types/types"; + +export default abstract class MetaProvider { + abstract rateLimit: number; + abstract id: string; + abstract url: string; + abstract formats: Format[]; + + public providerType: ProviderType = ProviderType.META; + public customProxy: string | undefined; + + async search(query: string, format?: Format, year?: number): Promise { + return undefined; + } + + async request(url: string, config: RequestInit = {}, proxyRequest = false): Promise { + return Http.request(url, config, proxyRequest, 0, this.customProxy); + } +} diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend-recode/src/mappings/index.ts index c0a4c4a..48b8ea8 100644 --- a/anify-backend-recode/src/mappings/index.ts +++ b/anify-backend-recode/src/mappings/index.ts @@ -1,6 +1,44 @@ -const ANIME_PROVIDERS: any[] = []; -const MANGA_PROVIDERS: any[] = []; -const META_PROVIDERS: any[] = []; -const INFORMATION_PROVIDERS: any[] = []; +import { Anime, AnimeInfo, Manga, MangaInfo } from "../types/types"; +import AnimeProvider from "./impl/anime"; +import NineAnime from "./impl/anime/nineanime"; +import InformationProvider from "./impl/information"; +import MangaProvider from "./impl/manga"; +import MetaProvider from "./impl/meta"; -export { ANIME_PROVIDERS, MANGA_PROVIDERS, INFORMATION_PROVIDERS, META_PROVIDERS }; +const ANIME_PROVIDERS: AnimeProvider[] = [new NineAnime()]; +const animeProviders: Record = ANIME_PROVIDERS.reduce( + (acc, provider) => { + acc[provider.id] = provider; + return acc; + }, + {} as Record, +); + +const MANGA_PROVIDERS: MangaProvider[] = []; +const mangaProviders: Record = MANGA_PROVIDERS.reduce( + (acc, provider) => { + acc[provider.id] = provider; + return acc; + }, + {} as Record, +); + +const INFORMATION_PROVIDERS: InformationProvider[] = []; +const infoProviders: Record> = INFORMATION_PROVIDERS.reduce( + (acc, provider) => { + acc[provider.id] = provider; + return acc; + }, + {} as Record>, +); + +const META_PROVIDERS: MetaProvider[] = []; +const metaProviders: Record = META_PROVIDERS.reduce( + (acc, provider) => { + acc[provider.id] = provider; + return acc; + }, + {} as Record, +); + +export { ANIME_PROVIDERS, animeProviders, MANGA_PROVIDERS, mangaProviders, INFORMATION_PROVIDERS, infoProviders, META_PROVIDERS, metaProviders }; diff --git a/anify-backend-recode/src/types/types.ts b/anify-backend-recode/src/types/types.ts index 1bff926..485c66a 100644 --- a/anify-backend-recode/src/types/types.ts +++ b/anify-backend-recode/src/types/types.ts @@ -99,6 +99,22 @@ export type Manga = { characters: Character[]; }; +export type AnimeInfo = Pick & { + rating: number | null; + popularity: number | null; +}; + +export type MangaInfo = Pick & { + rating: number | null; + popularity: number | null; +}; + +type SharedKeys = { + [K in keyof T]: K extends keyof U ? K : never; +}[keyof T]; + +export type MediaInfoKeys = SharedKeys; + export interface Character { name: string; image: string; From 19bc6e98836e95bf50e9a623369f56203dddb01c Mon Sep 17 00:00:00 2001 From: Eltik Date: Tue, 5 Sep 2023 21:45:56 -0400 Subject: [PATCH 05/77] Mappings working! --- anify-backend-recode/package.json | 1 + anify-backend-recode/src/database/impl/get.ts | 4 +- anify-backend-recode/src/index.ts | 5 +- anify-backend-recode/src/lib/impl/mappings.ts | 45 +- .../src/mappings/impl/base/anilist.ts | 856 ++++++++++++++++++ .../src/mappings/impl/base/index.ts | 35 + .../src/mappings/impl/information/anilist.ts | 681 ++++++++++++++ .../src/mappings/impl/information/index.ts | 18 +- .../src/mappings/impl/meta/tvdb.ts | 196 ++++ anify-backend-recode/src/mappings/index.ts | 22 +- anify-backend-recode/src/types/enums.ts | 1 + anify-backend-recode/src/types/types.ts | 28 +- 12 files changed, 1819 insertions(+), 73 deletions(-) create mode 100644 anify-backend-recode/src/mappings/impl/base/anilist.ts create mode 100644 anify-backend-recode/src/mappings/impl/base/index.ts create mode 100644 anify-backend-recode/src/mappings/impl/information/anilist.ts create mode 100644 anify-backend-recode/src/mappings/impl/meta/tvdb.ts diff --git a/anify-backend-recode/package.json b/anify-backend-recode/package.json index 5f2f085..d0b1dde 100644 --- a/anify-backend-recode/package.json +++ b/anify-backend-recode/package.json @@ -4,6 +4,7 @@ "type": "module", "scripts": { "start": "bun run dist/index.js", + "dev": "bun run src/index.ts", "build": "bun build ./src/index.ts --outdir ./dist --target node", "prettier": "prettier --write .", "eslint": "eslint --ext .ts src/** --fix", diff --git a/anify-backend-recode/src/database/impl/get.ts b/anify-backend-recode/src/database/impl/get.ts index 377761d..c7f4a04 100644 --- a/anify-backend-recode/src/database/impl/get.ts +++ b/anify-backend-recode/src/database/impl/get.ts @@ -2,9 +2,9 @@ import { db } from ".."; import { Anime, Manga } from "../../types/types"; export const get = async (id: string): Promise => { - const anime = await db.query(`SELECT * FROM anime WHERE $id`).get({ id: id }); + const anime = await db.query(`SELECT * FROM anime WHERE id = $id`).get({ $id: id }); if (!anime) { - return (await db.query(`SELECT * FROM manga WHERE $id`).get({ id: id })) as Manga | undefined; + return (await db.query(`SELECT * FROM manga WHERE id = $id`).get({ $id: id })) as Manga | undefined; } else { return anime as Anime; } diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 8bb35f6..537b436 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -2,9 +2,10 @@ import dotenv from "dotenv"; dotenv.config(); import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; -import { animeProviders } from "./mappings"; +import { loadMapping } from "./lib/impl/mappings"; +import { Type } from "./types/enums"; fetchCorsProxies().then(async (_) => { - const data = await animeProviders["9anime"].search("Mushoku Tensei"); + const data = await loadMapping({ id: "21", type: Type.ANIME }); console.log(data); }); diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend-recode/src/lib/impl/mappings.ts index 6d77aee..bda1594 100644 --- a/anify-backend-recode/src/lib/impl/mappings.ts +++ b/anify-backend-recode/src/lib/impl/mappings.ts @@ -3,7 +3,7 @@ import { get } from "../../database/impl/get"; import emitter, { Events } from ".."; import { Anime, AnimeInfo, Manga, MangaInfo, Result } from "../../types/types"; import { Format, MediaStatus, ProviderType, Season, Type } from "../../types/enums"; -import { ANIME_PROVIDERS, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, animeProviders, infoProviders, mangaProviders, metaProviders } from "../../mappings"; +import { ANIME_PROVIDERS, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, animeProviders, baseProviders, infoProviders, mangaProviders, metaProviders } from "../../mappings"; import { clean, slugify } from "../../helper/title"; import { findBestMatch2DArray, similarity } from "../../helper/stringSimilarity"; import { isString } from "../../helper"; @@ -35,7 +35,7 @@ export const loadMapping = async (data: { id: string; type: Type }, aniData?: An // Map only one media if (!aniData) { - aniData = await (infoProviders.anilist as any).getMedia(data.id); + aniData = await baseProviders.anilist.getMedia(data.id); } if (!aniData) { @@ -176,10 +176,12 @@ export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | Ma const best: Result = providerData[bestMatchIndex.bestMatchIndex]; // Add checks - if (best.format != Format.UNKNOWN && (aniData as any)?.format && (aniData as any)?.format != Format.UNKNOWN && best.format != aniData?.format) continue; - if (best.year != 0 && (aniData as any)?.year && (aniData as any)?.year != 0 && best.year != (aniData as any)?.year) continue; + if (best.format != Format.UNKNOWN && aniData?.format && aniData?.format != Format.UNKNOWN && best.format != aniData?.format) continue; + if (best.year != 0 && aniData?.year && aniData?.year != 0 && best.year != aniData?.year) continue; - const altTitles: any[] = Object.values((aniData as any)?.title).concat(aniData?.synonyms); + const altTitles: string[] = Object.values(aniData?.title ?? {}) + .concat(aniData?.synonyms ?? []) + .filter(isString); const sim = similarity(title, best.title, altTitles); @@ -187,7 +189,7 @@ export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | Ma if (mappings.filter((m) => m.data.id === best.id).length > 0) continue; mappings.push({ - id: (aniData as any).id, + id: aniData?.id ?? "", slug: slugify(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native ?? ""), data: best, similarity: sim.value, @@ -254,16 +256,8 @@ export async function createMedia(mappings: MappedResult[], type: Type): Promise duration: null, color: null, year: null, - rating: { - anilist: 0, - mal: 0, - kitsu: 0, - }, - popularity: { - anilist: 0, - mal: 0, - kitsu: 0, - }, + rating: null, + popularity: null, genres: [], format: Format.UNKNOWN, relations: [], @@ -308,16 +302,8 @@ export async function createMedia(mappings: MappedResult[], type: Type): Promise description: null, color: null, year: null, - rating: { - anilist: 0, - mal: 0, - kitsu: 0, - }, - popularity: { - anilist: 0, - mal: 0, - kitsu: 0, - }, + rating: null, + popularity: null, genres: [], format: Format.UNKNOWN, relations: [], @@ -415,6 +401,13 @@ function fillMediaInfo for (const crossLoad of crossLoadFields) { if (info[crossLoad as keyof (AnimeInfo | MangaInfo)]) { + if (media[crossLoad as keyof (Anime | Manga)] === null || media[crossLoad as keyof (Anime | Manga)] === undefined) { + (media[crossLoad as keyof (Anime | Manga)] as any) = {}; + + Object.assign(media[crossLoad as keyof (Anime | Manga)] ?? {}, { + [provider.id]: info[crossLoad as keyof (AnimeInfo | MangaInfo)], + }); + } if (media[crossLoad as keyof (Anime | Manga)] !== null && media[crossLoad as keyof (Anime | Manga)] !== undefined) { if (media[crossLoad as keyof (Anime | Manga)]) { (media[crossLoad as keyof (Anime | Manga)] as any)[provider.id] = info[crossLoad as keyof (AnimeInfo | MangaInfo)] as any; diff --git a/anify-backend-recode/src/mappings/impl/base/anilist.ts b/anify-backend-recode/src/mappings/impl/base/anilist.ts new file mode 100644 index 0000000..8afe36d --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/base/anilist.ts @@ -0,0 +1,856 @@ +import BaseProvider from "."; +import { Format, Genres, MediaStatus, Season, Type } from "../../../types/enums"; +import { AnimeInfo, Artwork, Character, MangaInfo, Relations } from "../../../types/types"; + +export default class AniListBase extends BaseProvider { + override id = "anilist"; + override url = "https://anilist.co"; + + private api = "https://graphql.anilist.co"; + + override async searchAdvanced(query: string, type: Type, formats: Format[], page: number, perPage: number, genres: Genres[] = [], genresExcluded: Genres[] = [], year = 0, tags: string[] = [], tagsExcluded: string[] = []): Promise { + const aniListArgs: { query: string; variables: { [key: string]: any } } = { + query: ` + query ($page: Int, $perPage: Int, $search: String, $type: MediaType, $format: [MediaFormat], $genres: [String], $genresExcluded: [String], $tags: [String], $tagsExcluded: [String]) { + Page(page: $page, perPage: $perPage) { + pageInfo { + total + currentPage + lastPage + hasNextPage + perPage + } + media(type: $type, format_in: $format, search: $search, genre_in: $genres, genre_not_in: $genresExcluded, tag_in: $tags, tag_not_in: $tagsExcluded) { + ${this.query} + } + } + } + `, + variables: { + search: query, + type: type, + format: formats, + page: page, + perPage: perPage, + genres: genres, + genresExclude: genresExcluded, + tags: tags.length > 0 ? tags : undefined, + tagsExclude: tagsExcluded, + }, + }; + + if (tags.length === 0) delete aniListArgs.variables.tags; + + const req = await this.request( + this.api, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + origin: "graphql.anilist.co", + }, + body: JSON.stringify(aniListArgs), + }, + true, + ); + const json = await req?.json(); + const media = json.data.Page.media; + + if (type === Type.ANIME) { + return media.map((data: Media) => { + const artwork: Artwork[] = []; + + if (data.coverImage.large) + artwork.push({ + type: "poster", + img: data.coverImage.large, + providerId: this.id, + }); + if (data.coverImage.extraLarge) + artwork.push({ + type: "poster", + img: data.coverImage.extraLarge, + providerId: this.id, + }); + if (data.bannerImage) + artwork.push({ + type: "banner", + img: data.bannerImage, + providerId: this.id, + }); + + const characters: Character[] = []; + const relations: Relations[] = []; + + for (const character of data.characters.edges) { + if (characters.length > 10) break; + const aliases: string[] = []; + + for (const alias of character.node.name.alternative) { + aliases.push(alias); + } + aliases.push(character.node.name.full); + + characters.push({ + voiceActor: { + name: character.voiceActors[0]?.name?.full ?? null, + image: character.voiceActors[0]?.image?.large ?? null, + }, + image: character.node.image.large, + name: character.node.name.full, + }); + } + + for (const relation of data.relations.edges) { + relations.push({ + id: String(relation.node.id), + format: relation.node.format, + relationType: relation.relationType, + title: relation.node.title, + type: relation.node.type, + }); + } + + return { + id: String(data.id), + title: { + english: data.title.english ?? null, + romaji: data.title.romaji ?? null, + native: data.title.native ?? null, + }, + trailer: null, + currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, + duration: data.duration ?? null, + coverImage: data.coverImage.extraLarge ?? null, + bannerImage: data.bannerImage ?? null, + popularity: Number(data.popularity), + synonyms: data.synonyms ?? [], + totalEpisodes: data.episodes ?? 0, + color: null, + status: data.status, + season: data.season as Season, + genres: (data.genres as Genres[]) ?? [], + rating: data.meanScore ? data.meanScore / 10 : null, + description: data.description ?? null, + format: data.format, + year: data.seasonYear ?? data.startDate?.year ?? null, + type: data.type, + countryOfOrigin: data.countryOfOrigin ?? null, + tags: data.tags.map((tag) => { + return tag.name; + }), + artwork: artwork, + relations: relations, + characters: characters, + } as AnimeInfo; + }); + } else { + return media.map((data: Media) => { + const artwork: Artwork[] = []; + + if (data.coverImage.large) + artwork.push({ + type: "poster", + img: data.coverImage.large, + providerId: this.id, + }); + if (data.coverImage.extraLarge) + artwork.push({ + type: "poster", + img: data.coverImage.extraLarge, + providerId: this.id, + }); + if (data.bannerImage) + artwork.push({ + type: "banner", + img: data.bannerImage, + providerId: this.id, + }); + + const characters: Character[] = []; + const relations: Relations[] = []; + + for (const character of data.characters.edges) { + if (characters.length > 10) break; + const aliases: string[] = []; + + for (const alias of character.node.name.alternative) { + aliases.push(alias); + } + aliases.push(character.node.name.full); + + characters.push({ + voiceActor: { + name: character.voiceActors[0]?.name?.full ?? null, + image: character.voiceActors[0]?.image?.large ?? null, + }, + image: character.node.image.large, + name: character.node.name.full, + }); + } + + for (const relation of data.relations.edges) { + relations.push({ + id: String(relation.node.id), + format: relation.node.format, + relationType: relation.relationType, + title: relation.node.title, + type: relation.node.type, + }); + } + + return { + id: String(data.id), + title: { + english: data.title.english ?? null, + romaji: data.title.romaji ?? null, + native: data.title.native ?? null, + }, + coverImage: data.coverImage.extraLarge ?? null, + bannerImage: data.bannerImage ?? null, + popularity: Number(data.popularity), + synonyms: data.synonyms ?? [], + totalChapters: data.chapters ?? 0, + totalVolumes: data.volumes ?? 0, + color: null, + status: data.status, + genres: (data.genres as Genres[]) ?? [], + rating: data.meanScore ? data.meanScore / 10 : null, + description: data.description ?? null, + format: data.format, + year: data.seasonYear ?? data.startDate?.year ?? null, + type: data.type, + countryOfOrigin: data.countryOfOrigin ?? null, + tags: data.tags.map((tag) => tag.name), + artwork: artwork, + characters: characters, + relations: relations, + } as MangaInfo; + }); + } + } + + override getCurrentSeason(): Season { + return Season.SUMMER; + } + + override async getMedia(id: string): Promise { + const query = `query ($id: Int) { + Media (id: $id) { + ${this.query} + } + }`; + const variables = { + id: id, + }; + + const req = await this.request( + this.api, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + origin: "graphql.anilist.co", + }, + body: JSON.stringify({ + query, + variables, + }), + }, + true, + ); + const data: Media = (await req.json()).data?.Media; + if (!data) return undefined; + + const characters: Character[] = []; + const relations: Relations[] = []; + + for (const character of data.characters.edges) { + if (characters.length > 10) break; + const aliases: string[] = []; + + for (const alias of character.node.name.alternative) { + aliases.push(alias); + } + aliases.push(character.node.name.full); + + characters.push({ + voiceActor: { + name: character.voiceActors[0]?.name?.full ?? null, + image: character.voiceActors[0]?.image?.large ?? null, + }, + image: character.node.image.large, + name: character.node.name.full, + }); + } + + for (const relation of data.relations.edges) { + relations.push({ + id: String(relation.node.id), + format: relation.node.format, + relationType: relation.relationType, + title: relation.node.title, + type: relation.node.type, + }); + } + + return { + id: String(data.id), + title: { + english: data.title.english ?? null, + romaji: data.title.romaji ?? null, + native: data.title.native ?? null, + }, + trailer: null, + currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, + duration: data.duration ?? null, + coverImage: data.coverImage.extraLarge ?? null, + bannerImage: data.bannerImage ?? null, + popularity: Number(data.popularity), + synonyms: data.synonyms ?? [], + totalEpisodes: data.episodes ?? 0, + totalChapters: data.chapters ?? 0, + color: null, + status: data.status as MediaStatus, + season: data.season as Season, + genres: (data.genres as Genres[]) ?? [], + rating: data.meanScore ? data.meanScore / 10 : null, + description: data.description ?? null, + type: data.type, + format: data.format, + year: data.seasonYear ?? data.startDate?.year ?? null, + countryOfOrigin: data.countryOfOrigin ?? null, + tags: data.tags.map((tag) => tag.name), + relations, + characters, + artwork: [ + { + type: "poster", + img: data.coverImage.extraLarge, + providerId: this.id, + }, + { + type: "banner", + img: data.bannerImage, + providerId: this.id, + }, + ], + totalVolumes: data.volumes ?? 0, + }; + } + + override async fetchSeasonal(type: Type, formats: Format[]): Promise<{ trending: AnimeInfo[] | MangaInfo[]; seasonal: AnimeInfo[] | MangaInfo[]; popular: AnimeInfo[] | MangaInfo[]; top: AnimeInfo[] | MangaInfo[] } | undefined> { + const aniListArgs = { + query: ` + query($season: MediaSeason, $seasonYear: Int, $format: [MediaFormat], $page: Int, $perPage: Int, $type: MediaType) { + trending: Page(page: $page, perPage: $perPage) { + media(sort: TRENDING_DESC, type: $type, isAdult: false, format_in: $format) { + ...media + } + } + season: Page(page: $page, perPage: $perPage) { + media(season: $season, seasonYear: $seasonYear, sort: POPULARITY_DESC, type: $type, isAdult: false, format_in: $format) { + ...media + } + } + popular: Page(page: $page, perPage: $perPage) { + media(sort: POPULARITY_DESC, type: $type, isAdult: false, format_in: $format) { + ...media + } + } + top: Page(page: $page, perPage: $perPage) { + media(sort: SCORE_DESC, type: $type, isAdult: false, format_in: $format) { + ...media + } + } + } + + fragment media on Media { + ${this.query} + } + `, + variables: { + type: type, + season: this.getCurrentSeason(), + seasonYear: 2023, + format: formats, + page: 0, + perPage: 20, + }, + }; + + const req = await ( + await this.request( + this.api, + { + body: JSON.stringify(aniListArgs), + method: "POST", + headers: { + "Content-Type": "application/json", + Origin: "https://anilist.co", + }, + }, + true, + ) + ).json(); + + const data = req?.data; + if (!data) { + return undefined; + } + + const trending = data.trending.media?.map((data: Media) => { + return this.anilistMediaGenerator(data); + }); + + const seasonal = data.season.media?.map((data: Media) => { + return this.anilistMediaGenerator(data); + }); + + const popular = data.popular.media?.map((data: Media) => { + return this.anilistMediaGenerator(data); + }); + + const top = data.top.media?.map((data: Media) => { + return this.anilistMediaGenerator(data); + }); + + return { + trending, + seasonal, + popular, + top, + }; + } + + private anilistMediaGenerator(data: any): AnimeInfo | MangaInfo { + return { + id: String(data.id), + title: { + english: data.title.english ?? null, + romaji: data.title.romaji ?? null, + native: data.title.native ?? null, + }, + coverImage: data.coverImage.extraLarge ?? null, + bannerImage: data.bannerImage ?? null, + popularity: Number(data.popularity), + synonyms: data.synonyms ?? [], + totalChapters: data.chapters ?? 0, + totalVolumes: data.volumes ?? 0, + color: null, + status: data.status, + genres: (data.genres as Genres[]) ?? [], + rating: data.meanScore ? data.meanScore / 10 : null, + description: data.description ?? null, + type: data.type, + format: data.format, + countryOfOrigin: data.countryOfOrigin ?? null, + year: data.seasonYear ?? data.startDate?.year ?? null, + tags: data.tags.map((tag: { name: string }) => tag.name), + artwork: [ + { + type: "poster", + img: data.coverImage.extraLarge, + providerId: this.id, + }, + { + type: "banner", + img: data.bannerImage, + providerId: this.id, + }, + ], + characters: [], + currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, + duration: data.duration ?? null, + relations: [], + season: data.season as Season, + trailer: null, + totalEpisodes: data.episodes ?? 0, + }; + } + + public async batchRequest(queries: string[], maxQueries: number): Promise { + const results: any[] = []; + + const processBatch = async (batch: string[]) => { + const currentQuery = `{${batch.join("\n")}}`; + const result = await this.executeGraphQLQuery(currentQuery); + if (result) { + const data = await result.json(); + results.push(...Object.values(data)); + } + }; + + const batchedQueries: string[][] = []; + for (let i = 0; i < queries.length; i += maxQueries) { + batchedQueries.push(queries.slice(i, i + maxQueries)); + } + + for await (const batch of batchedQueries) { + await processBatch(batch); + } + + return results; + } + + private async executeGraphQLQuery(query: string) { + const variables = {}; + return await this.request( + this.api, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + origin: "graphql.anilist.co", + }, + body: JSON.stringify({ + query, + variables, + }), + }, + true, + ).catch((err) => { + console.error(err); + return null; + }); + } + + public query = ` + id + idMal + title { + romaji + english + native + userPreferred + } + coverImage { + extraLarge + large + color + } + bannerImage + startDate { + year + month + day + } + endDate { + year + month + day + } + description + season + seasonYear + type + format + status(version: 2) + episodes + duration + chapters + volumes + genres + synonyms + source(version: 3) + isAdult + meanScore + averageScore + popularity + favourites + countryOfOrigin + isLicensed + characters { + edges { + voiceActors { + id + name { + first + middle + last + full + native + } + image { + large + } + gender + age + dateOfBirth { + year + month + day + } + languageV2 + } + role + node { + id + name { + first + middle + last + full + native + alternative + alternativeSpoiler + } + age + image { + large + } + description + modNotes + siteUrl + } + } + } + relations { + edges { + id + relationType(version: 2) + node { + id + title { + english + romaji + native + } + format + type + status(version: 2) + bannerImage + coverImage { + large + } + } + } + } + streamingEpisodes { + title + thumbnail + url + } + trailer { + id + site + } + tags { + id + name + } + `; +} + +interface Media { + id: number; + idMal: number; + title: { + english?: string; + romaji: string; + native: string; + userPreferred: string; + }; + coverImage: { + extraLarge: string; + large: string; + color?: string; + }; + bannerImage: string; + startDate: { + year: number; + month: number; + day: number; + }; + endDate: { + year: number; + month: number; + day: number; + }; + description: string; + season: "WINTER" | "SPRING" | "SUMMER" | "FALL"; + seasonYear: number; + type: Type; + format: Format; + status: "FINISHED" | "RELEASING" | "NOT_YET_RELEASED" | "CANCELLED"; + episodes?: number; + duration?: number; + chapters?: number; + volumes?: number; + genres: string[]; + synonyms: string[]; + source: "ORIGINAL" | "LIGHT_NOVEL" | "VISUAL_NOVEL" | "VIDEO_GAME" | "OTHER" | "NOVEL" | "MANGA" | "DOUJINSHI" | "ANIME" | "WEB_MANGA" | "BOOK" | "CARD_GAME" | "COMIC" | "GAME" | "MUSIC" | "NOVEL" | "ONE_SHOT" | "OTHER" | "PICTURE_BOOK" | "RADIO" | "TV" | "UNKNOWN"; + isAdult: boolean; + meanScore: number; + averageScore: number; + popularity: number; + favourites: number; + countryOfOrigin: string; + isLicensed: boolean; + airingSchedule: { + edges: { + node: { + airingAt?: any; + timeUntilAiring?: any; + episode?: any; + }; + }; + }; + relations: { + edges: [RelationsNode]; + }; + characters: { + edges: [ + { + role: string; + voiceActors: [ + { + id: number; + name: { + first: string; + middle: string; + last: string; + full: string; + native: string; + }; + languageV2: string; + image: { + large: string; + }; + gender: string | null; + age: number | null; + dateOfBirth: { + year: number | null; + month: number | null; + day: number | null; + }; + }, + ]; + node: { + id: number; + name: { + first: string; + middle: string; + last: string; + full: string; + native: string; + alternative: string[]; + alternativeSpoiler: string[]; + }; + age: number | null; + image: { + large: string; + }; + description: string; + modNotes: string; + siteUrl: string; + }; + }, + ]; + }; + studios: { + edges: { + isMain: boolean; + node: { + id: number; + name: string; + }; + }; + }; + streamingEpisodes: [ + { + title?: string; + thumbnail?: string; + url?: string; + }, + ]; + trailer: { + id: string; + site: string; + }; + tags: [{ id: number; name: string }]; +} + +interface RelationsNode { + id: number; + relationType: string; + node: { + id: number; + title: { + english: string | null; + romaji: string | null; + native: string | null; + }; + format: Format; + type: Type; + status: string; + bannerImage: string; + coverImage: { + large: string; + }; + }; +} + +interface Schedule { + id: number; + episode: number; + airingAt: number; + media: { + id: number; + idMal: number; + title: { + romaji: string; + native: string; + english: string | null; + }; + startDate: { + year: number; + month: number; + day: number; + }; + endDate: { + year: number; + month: number; + day: number; + }; + status: string; + season: string | null; + format: string; + genres: string[]; + synonyms: string[]; + duration: number | null; + popularity: number; + episodes: number; + source: string; + countryOfOrigin: string; + hashtag: string | null; + averageScore: number | null; + siteUrl: string; + description: string | null; + bannerImage: string | null; + isAdult: boolean; + coverImage: { + extraLarge: string; + color: string; + }; + trailer: string | null; + externalLinks: { + site: string; + url: string; + }[]; + rankings: any[]; + studios: { + nodes: { + id: number; + name: string; + siteUrl: string; + }[]; + }; + relations: { + edges: any[]; + }; + }; +} diff --git a/anify-backend-recode/src/mappings/impl/base/index.ts b/anify-backend-recode/src/mappings/impl/base/index.ts new file mode 100644 index 0000000..8989ce6 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/base/index.ts @@ -0,0 +1,35 @@ +import Http from "../../../helper/request"; +import { Format, Genres, ProviderType, Season, Type } from "../../../types/enums"; +import { Anime, AnimeInfo, Manga, MangaInfo } from "../../../types/types"; + +export default abstract class BaseProvider { + abstract id: string; + abstract url: string; + + public providerType: ProviderType = ProviderType.BASE; + public customProxy: string | undefined; + + async searchAdvanced(query: string, type: Type, formats: Format[], page: number, perPage: number, genres: Genres[] = [], genresExcluded: Genres[] = [], year = 0, tags: string[] = [], tagsExcluded: string[] = []): Promise { + return undefined; + } + + getCurrentSeason(): Season { + return Season.SUMMER; + } + + async getMedia(id: string): Promise { + return undefined; + } + + async fetchSeasonal(type: Type, formats: Format[]): Promise<{ trending: AnimeInfo[] | MangaInfo[]; seasonal: AnimeInfo[] | MangaInfo[]; popular: AnimeInfo[] | MangaInfo[]; top: AnimeInfo[] | MangaInfo[] } | undefined> { + return undefined; + } + + async fetchSchedule(): Promise { + return undefined; + } + + async request(url: string, config: RequestInit = {}, proxyRequest = true): Promise { + return Http.request(url, config, proxyRequest, 0, this.customProxy); + } +} diff --git a/anify-backend-recode/src/mappings/impl/information/anilist.ts b/anify-backend-recode/src/mappings/impl/information/anilist.ts new file mode 100644 index 0000000..76fd7d8 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/information/anilist.ts @@ -0,0 +1,681 @@ +import InformationProvider from "."; +import { Format, Genres, MediaStatus, Season, Type } from "../../../types/enums"; +import { Anime, AnimeInfo, Artwork, Character, Manga, MangaInfo, MediaInfoKeys, Relations } from "../../../types/types"; + +export default class AniList extends InformationProvider { + override id = "anilist"; + override url = "https://anilist.co"; + + private api = "https://graphql.anilist.co"; + + override get priorityArea(): MediaInfoKeys[] { + return ["bannerImage", "relations", "color"]; + } + + override get sharedArea(): MediaInfoKeys[] { + return ["synonyms", "genres", "tags", "artwork", "characters"]; + } + + override async search(query: string, type: Type, formats: Format[], page?: number, perPage?: number): Promise { + const aniListArgs = { + query: ` + query($page: Int, $perPage: Int, $search: String, $type: MediaType, $format: [MediaFormat]) { + Page(page: $page, perPage: $perPage) { + pageInfo { + total + currentPage + lastPage + hasNextPage + perPage + } + media(type: $type, format_in: $format, search: $search) { + ${this.query} + } + } + } + `, + variables: { + search: query, + type: type, + format: formats, + page: page ? page : 0, + perPage: perPage ? perPage : 15, + }, + }; + const req = await this.request( + this.api, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + origin: "graphql.anilist.co", + }, + body: JSON.stringify(aniListArgs), + }, + true, + ); + const json = await req?.json(); + const media = json.data.Page.media; + + if (type === Type.ANIME) { + return media.map((data: Media) => { + const artwork: Artwork[] = []; + + if (data.coverImage.large) + artwork.push({ + type: "poster", + img: data.coverImage.large, + providerId: this.id, + }); + if (data.coverImage.extraLarge) + artwork.push({ + type: "poster", + img: data.coverImage.extraLarge, + providerId: this.id, + }); + if (data.bannerImage) + artwork.push({ + type: "banner", + img: data.bannerImage, + providerId: this.id, + }); + + const characters: Character[] = []; + const relations: Relations[] = []; + + for (const character of data.characters.edges) { + if (characters.length > 10) break; + const aliases: string[] = []; + + for (const alias of character.node.name.alternative) { + aliases.push(alias); + } + aliases.push(character.node.name.full); + + characters.push({ + voiceActor: { + name: character.voiceActors[0]?.name?.full ?? null, + image: character.voiceActors[0]?.image?.large ?? null, + }, + image: character.node.image.large, + name: character.node.name.full, + }); + } + + for (const relation of data.relations.edges) { + relations.push({ + id: String(relation.node.id), + format: relation.node.format, + relationType: relation.relationType, + title: relation.node.title, + type: relation.node.type, + }); + } + + return { + id: String(data.id), + title: { + english: data.title.english ?? null, + romaji: data.title.romaji ?? null, + native: data.title.native ?? null, + }, + trailer: null, + currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, + duration: data.duration ?? null, + coverImage: data.coverImage.extraLarge ?? null, + bannerImage: data.bannerImage ?? null, + popularity: Number(data.popularity), + synonyms: data.synonyms ?? [], + totalEpisodes: data.episodes ?? 0, + color: null, + status: data.status, + season: data.season as Season, + genres: (data.genres as Genres[]) ?? [], + rating: data.meanScore ? data.meanScore / 10 : null, + description: data.description ?? null, + format: data.format, + year: data.seasonYear ?? data.startDate?.year ?? null, + type: data.type, + countryOfOrigin: data.countryOfOrigin ?? null, + tags: data.tags.map((tag) => { + return tag.name; + }), + artwork: artwork, + relations: relations, + characters: characters, + } as AnimeInfo; + }); + } else { + return media.map((data: Media) => { + const artwork: Artwork[] = []; + + if (data.coverImage.large) + artwork.push({ + type: "poster", + img: data.coverImage.large, + providerId: this.id, + }); + if (data.coverImage.extraLarge) + artwork.push({ + type: "poster", + img: data.coverImage.extraLarge, + providerId: this.id, + }); + if (data.bannerImage) + artwork.push({ + type: "banner", + img: data.bannerImage, + providerId: this.id, + }); + + const characters: Character[] = []; + const relations: Relations[] = []; + + for (const character of data.characters.edges) { + if (characters.length > 10) break; + const aliases: string[] = []; + + for (const alias of character.node.name.alternative) { + aliases.push(alias); + } + aliases.push(character.node.name.full); + + characters.push({ + voiceActor: { + name: character.voiceActors[0]?.name?.full ?? null, + image: character.voiceActors[0]?.image?.large ?? null, + }, + image: character.node.image.large, + name: character.node.name.full, + }); + } + + for (const relation of data.relations.edges) { + relations.push({ + id: String(relation.node.id), + format: relation.node.format, + relationType: relation.relationType, + title: relation.node.title, + type: relation.node.type, + }); + } + + return { + id: String(data.id), + title: { + english: data.title.english ?? null, + romaji: data.title.romaji ?? null, + native: data.title.native ?? null, + }, + coverImage: data.coverImage.extraLarge ?? null, + bannerImage: data.bannerImage ?? null, + popularity: Number(data.popularity), + synonyms: data.synonyms ?? [], + totalChapters: data.chapters ?? 0, + totalVolumes: data.volumes ?? 0, + color: null, + status: data.status, + genres: (data.genres as Genres[]) ?? [], + rating: data.meanScore ? data.meanScore / 10 : null, + description: data.description ?? null, + format: data.format, + year: data.seasonYear ?? data.startDate?.year ?? null, + type: data.type, + countryOfOrigin: data.countryOfOrigin ?? null, + tags: data.tags.map((tag) => tag.name), + artwork: artwork, + characters: characters, + relations: relations, + } as MangaInfo; + }); + } + } + + override async info(media: Anime | Manga): Promise { + const anilistId = media.id; + + const query = `query ($id: Int) { + Media (id: $id) { + ${this.query} + } + }`; + const variables = { + id: anilistId, + }; + + const req = await this.request( + this.api, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + origin: "graphql.anilist.co", + }, + body: JSON.stringify({ + query, + variables, + }), + }, + true, + ); + //const data: Media = (await req.json()).data.Media; + const text = await req.text(); + let data: any = undefined; + try { + data = JSON.parse(text).data.Media; + } catch (e) { + console.log(text); + } + if (!data) throw new Error("No data returned from AniList"); + + const artwork: Artwork[] = []; + + if (data.coverImage.large) + artwork.push({ + type: "poster", + img: data.coverImage.large, + providerId: this.id, + }); + if (data.coverImage.extraLarge) + artwork.push({ + type: "poster", + img: data.coverImage.extraLarge, + providerId: this.id, + }); + if (data.bannerImage) + artwork.push({ + type: "banner", + img: data.bannerImage, + providerId: this.id, + }); + + const characters: Character[] = []; + const relations: Relations[] = []; + + for (const character of data.characters.edges) { + if (characters.length > 10) break; + const aliases: string[] = []; + + for (const alias of character.node.name.alternative) { + aliases.push(alias); + } + aliases.push(character.node.name.full); + + characters.push({ + voiceActor: { + name: character.voiceActors[0]?.name?.full ?? null, + image: character.voiceActors[0]?.image?.large ?? null, + }, + image: character.node.image.large, + name: character.node.name.full, + }); + } + + for (const relation of data.relations.edges) { + relations.push({ + id: String(relation.node.id), + format: relation.node.format, + relationType: relation.relationType, + title: relation.node.title, + type: relation.node.type, + }); + } + + return { + id: String(data.id), + title: { + english: data.title.english ?? null, + romaji: data.title.romaji ?? null, + native: data.title.native ?? null, + }, + trailer: null, + currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, + duration: data.duration ?? null, + coverImage: data.coverImage.extraLarge ?? null, + bannerImage: data.bannerImage ?? null, + popularity: Number(data.popularity), + synonyms: data.synonyms ?? [], + totalEpisodes: data.episodes ?? 0, + totalChapters: data.chapters ?? 0, + totalVolumes: data.volumes ?? 0, + color: data.coverImage.color ?? null, + status: data.status as MediaStatus, + season: data.season as Season, + genres: (data.genres as Genres[]) ?? [], + rating: data.meanScore ? data.meanScore / 10 : null, + description: data.description ?? null, + type: data.type, + format: data.format, + year: data.seasonYear ?? data.startDate?.year ?? null, + countryOfOrigin: data.countryOfOrigin ?? null, + tags: data.tags.map((tag: { name: string }) => tag.name), + relations: relations, + artwork, + characters, + }; + } + + public async batchRequest(queries: string[], maxQueries: number): Promise { + const results: any[] = []; + + const processBatch = async (batch: string[]) => { + const currentQuery = `{${batch.join("\n")}}`; + const result = await this.executeGraphQLQuery(currentQuery); + if (result) { + const data = await result.json(); + results.push(...Object.values(data)); + } + }; + + const batchedQueries: string[][] = []; + for (let i = 0; i < queries.length; i += maxQueries) { + batchedQueries.push(queries.slice(i, i + maxQueries)); + } + + for await (const batch of batchedQueries) { + await processBatch(batch); + } + + return results; + } + + private async executeGraphQLQuery(query: string) { + const variables = {}; + return await this.request( + this.api, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + origin: "graphql.anilist.co", + }, + body: JSON.stringify({ + query, + variables, + }), + }, + true, + ).catch((err) => { + console.error(err); + return null; + }); + } + + public query = ` + id + idMal + title { + romaji + english + native + userPreferred + } + coverImage { + extraLarge + large + color + } + bannerImage + startDate { + year + month + day + } + endDate { + year + month + day + } + description + season + seasonYear + type + format + status(version: 2) + episodes + duration + chapters + volumes + genres + synonyms + source(version: 3) + isAdult + meanScore + averageScore + popularity + favourites + countryOfOrigin + isLicensed + characters { + edges { + voiceActors { + id + name { + first + middle + last + full + native + } + image { + large + } + gender + age + dateOfBirth { + year + month + day + } + languageV2 + } + role + node { + id + name { + first + middle + last + full + native + alternative + alternativeSpoiler + } + age + image { + large + } + description + modNotes + siteUrl + } + } + } + relations { + edges { + id + relationType(version: 2) + node { + id + title { + english + romaji + native + } + format + type + status(version: 2) + bannerImage + coverImage { + large + } + } + } + } + streamingEpisodes { + title + thumbnail + url + } + trailer { + id + site + } + tags { + id + name + } + `; +} + +interface Media { + id: number; + idMal: number; + title: { + english?: string; + romaji: string; + native: string; + userPreferred: string; + }; + coverImage: { + extraLarge: string; + large: string; + color?: string; + }; + bannerImage: string; + startDate: { + year: number; + month: number; + day: number; + }; + endDate: { + year: number; + month: number; + day: number; + }; + description: string; + season: "WINTER" | "SPRING" | "SUMMER" | "FALL"; + seasonYear: number; + type: Type; + format: Format; + status: "FINISHED" | "RELEASING" | "NOT_YET_RELEASED" | "CANCELLED"; + episodes?: number; + duration?: number; + chapters?: number; + volumes?: number; + genres: string[]; + synonyms: string[]; + source: "ORIGINAL" | "LIGHT_NOVEL" | "VISUAL_NOVEL" | "VIDEO_GAME" | "OTHER" | "NOVEL" | "MANGA" | "DOUJINSHI" | "ANIME" | "WEB_MANGA" | "BOOK" | "CARD_GAME" | "COMIC" | "GAME" | "MUSIC" | "NOVEL" | "ONE_SHOT" | "OTHER" | "PICTURE_BOOK" | "RADIO" | "TV" | "UNKNOWN"; + isAdult: boolean; + meanScore: number; + averageScore: number; + popularity: number; + favourites: number; + countryOfOrigin: string; + isLicensed: boolean; + airingSchedule: { + edges: { + node: { + airingAt?: any; + timeUntilAiring?: any; + episode?: any; + }; + }; + }; + relations: { + edges: [RelationsNode]; + }; + characters: { + edges: [ + { + role: string; + voiceActors: [ + { + id: number; + name: { + first: string; + middle: string; + last: string; + full: string; + native: string; + }; + languageV2: string; + image: { + large: string; + }; + gender: string | null; + age: number | null; + dateOfBirth: { + year: number | null; + month: number | null; + day: number | null; + }; + }, + ]; + node: { + id: number; + name: { + first: string; + middle: string; + last: string; + full: string; + native: string; + alternative: string[]; + alternativeSpoiler: string[]; + }; + age: number | null; + image: { + large: string; + }; + description: string; + modNotes: string; + siteUrl: string; + }; + }, + ]; + }; + studios: { + edges: { + isMain: boolean; + node: { + id: number; + name: string; + }; + }; + }; + streamingEpisodes: [ + { + title?: string; + thumbnail?: string; + url?: string; + }, + ]; + trailer: { + id: string; + site: string; + }; + tags: [{ id: number; name: string }]; +} + +interface RelationsNode { + id: number; + relationType: string; + node: { + id: number; + title: { + english: string | null; + romaji: string | null; + native: string | null; + }; + format: Format; + type: Type; + status: string; + bannerImage: string; + coverImage: { + large: string; + }; + }; +} diff --git a/anify-backend-recode/src/mappings/impl/information/index.ts b/anify-backend-recode/src/mappings/impl/information/index.ts index c03c0c7..3269933 100644 --- a/anify-backend-recode/src/mappings/impl/information/index.ts +++ b/anify-backend-recode/src/mappings/impl/information/index.ts @@ -1,6 +1,6 @@ import Http from "../../../helper/request"; import { Format, ProviderType, Type } from "../../../types/enums"; -import { Anime, Manga } from "../../../types/types"; +import { Anime, AnimeInfo, Manga, MangaInfo, MediaInfoKeys } from "../../../types/types"; export default abstract class InformationProvider { abstract id: string; @@ -29,19 +29,3 @@ export default abstract class InformationProvider & { - rating: number | null; - popularity: number | null; -}; - -export type MangaInfo = Pick & { - rating: number | null; - popularity: number | null; -}; - -type SharedKeys = { - [K in keyof T]: K extends keyof U ? K : never; -}[keyof T]; - -export type MediaInfoKeys = SharedKeys; diff --git a/anify-backend-recode/src/mappings/impl/meta/tvdb.ts b/anify-backend-recode/src/mappings/impl/meta/tvdb.ts new file mode 100644 index 0000000..e9a0a6d --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/meta/tvdb.ts @@ -0,0 +1,196 @@ +import MetaProvider from "."; +import { Format } from "../../../types/enums"; +import { Result } from "../../../types/types"; + +export default class TheTVDB extends MetaProvider { + override rateLimit = 500; + override id = "tvdb"; + override url = "https://thetvdb.com"; + override formats: Format[] = [Format.TV, Format.MOVIE, Format.ONA, Format.SPECIAL, Format.TV_SHORT, Format.OVA]; + + private tvdbApiUrl = "https://api4.thetvdb.com/v4"; + + private apiKeys = ["f5744a13-9203-4d02-b951-fbd7352c1657", "8f406bec-6ddb-45e7-8f4b-e1861e10f1bb", "5476e702-85aa-45fd-a8da-e74df3840baf", "51020266-18f7-4382-81fc-75a4014fa59f"]; + + override async search(query: string, format?: Format, year?: number): Promise { + const results: Result[] = []; + + const isSeason = query.toLowerCase().includes("season"); + + if (isSeason) { + query = query.toLowerCase().replace("season", ""); + } + + const token = await this.getToken(this.apiKeys[Math.floor(Math.random() * this.apiKeys.length)]); + + const formattedType = format === Format.TV || Format.TV_SHORT || Format.SPECIAL ? "series" : format === Format.MOVIE ? "movie" : undefined; + + const data = await this.request( + `${this.tvdbApiUrl}/search?query=${encodeURIComponent(query)}${year && !isSeason ? `&year=${year}` : ""}${formattedType ? `&type=${formattedType}` : ""}`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + }, + false, + ); + + if (data?.ok) { + const searchData: Search[] = (await data.json()).data; + for (const data of searchData) { + if (data.primary_type != TVDBType.SERIES && data.primary_type != TVDBType.MOVIE) continue; + if (isSeason) data.year = "0"; + + results.push({ + id: `/${data.primary_type}/${data.tvdb_id}`, + format: Format.UNKNOWN, + title: data.name, + altTitles: data.aliases ?? [], + img: data.image_url, + year: Number(data.year ?? 0) ?? 0, + providerId: this.id, + }); + } + } + + return results; + } + + private async getToken(key: string): Promise { + const data: Response | undefined = await this.request( + `${this.tvdbApiUrl}/login`, + { + body: JSON.stringify({ + apikey: `${key}`, + }), + method: "POST", + headers: { + "Content-Type": "application/json", + }, + }, + false, + ).catch((err) => { + console.error(err); + return undefined; + }); + if (!data) return undefined; + + if (data.ok) { + return (await data.json()).data.token as string; + } + + return undefined; + } +} + +/* Search Types */ +interface Search { + objectID: string; + country?: Country; + director?: string; + extended_title?: string; + genres?: Genre[]; + id: string; + image_url: string; + name: string; + overview?: string; + primary_language?: PrimaryLanguage; + primary_type: TVDBType; + status?: Status; + type: TVDBType; + tvdb_id: string; + year?: string; + slug?: string; + overviews?: Overviews; + translations: Overviews; + remote_ids?: RemoteID[]; + thumbnail?: string; + aliases?: string[]; + first_air_time?: Date; + network?: string; + studios?: string[]; +} + +enum Country { + CZE = "cze", + JPN = "jpn", + USA = "usa", +} + +enum Genre { + ACTION = "Action", + ADVENTURE = "Adventure", + ANIMATION = "Animation", + ANIME = "Anime", + CHILDREN = "Children", + COMEDY = "Comedy", + DRAMA = "Drama", + FAMILY = "Family", + FANTASY = "Fantasy", + SPORT = "Sport", +} + +interface Overviews { + eng?: string; + fra?: string; + ita?: string; + jpn?: string; + pol?: string; + pt?: string; + spa?: string; + por?: string; + ara?: string; + cat?: string; + deu?: string; + heb?: string; + kor?: string; + msa?: string; + rus?: string; + srp?: string; + tur?: string; + zho?: string; + hun?: string; + cha?: string; + nld?: string; + tha?: string; + ces?: string; +} + +enum PrimaryLanguage { + CES = "ces", + ENG = "eng", + ITA = "ita", + JPN = "jpn", +} + +enum TVDBType { + LIST = "list", + MOVIE = "movie", + SERIES = "series", +} + +interface RemoteID { + id: string; + type: number; + sourceName: SourceName; +} + +enum SourceName { + EIDR = "EIDR", + FACEBOOK = "Facebook", + FANSITE = "Fan Site", + IMDB = "IMDB", + INSTAGRAM = "Instagram", + OFFICIAL_WEBSITE = "Official Website", + TMS_ZAP2It = "TMS (Zap2It)", + TMDB = "TheMovieDB.com", + TWITTER = "Twitter", + YOUTUBE = "Youtube", +} + +enum Status { + CONTINUING = "Continuing", + ENDED = "Ended", + RELEASED = "Released", + UPCOMING = "Upcoming", +} diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend-recode/src/mappings/index.ts index 48b8ea8..a3142cd 100644 --- a/anify-backend-recode/src/mappings/index.ts +++ b/anify-backend-recode/src/mappings/index.ts @@ -1,11 +1,16 @@ import { Anime, AnimeInfo, Manga, MangaInfo } from "../types/types"; import AnimeProvider from "./impl/anime"; +import AnimePahe from "./impl/anime/animepahe"; import NineAnime from "./impl/anime/nineanime"; +import BaseProvider from "./impl/base"; +import AniListBase from "./impl/base/anilist"; import InformationProvider from "./impl/information"; +import AniList from "./impl/information/anilist"; import MangaProvider from "./impl/manga"; import MetaProvider from "./impl/meta"; +import TheTVDB from "./impl/meta/tvdb"; -const ANIME_PROVIDERS: AnimeProvider[] = [new NineAnime()]; +const ANIME_PROVIDERS: AnimeProvider[] = [new NineAnime(), new AnimePahe()]; const animeProviders: Record = ANIME_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; @@ -23,7 +28,7 @@ const mangaProviders: Record = MANGA_PROVIDERS.reduce( {} as Record, ); -const INFORMATION_PROVIDERS: InformationProvider[] = []; +const INFORMATION_PROVIDERS: InformationProvider[] = [new AniList()]; const infoProviders: Record> = INFORMATION_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; @@ -32,7 +37,7 @@ const infoProviders: Record>, ); -const META_PROVIDERS: MetaProvider[] = []; +const META_PROVIDERS: MetaProvider[] = [new TheTVDB()]; const metaProviders: Record = META_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; @@ -41,4 +46,13 @@ const metaProviders: Record = META_PROVIDERS.reduce( {} as Record, ); -export { ANIME_PROVIDERS, animeProviders, MANGA_PROVIDERS, mangaProviders, INFORMATION_PROVIDERS, infoProviders, META_PROVIDERS, metaProviders }; +const BASE_PROVIDERS: BaseProvider[] = [new AniListBase()]; +const baseProviders: Record = BASE_PROVIDERS.reduce( + (acc, provider) => { + acc[provider.id] = provider; + return acc; + }, + {} as Record, +); + +export { ANIME_PROVIDERS, animeProviders, MANGA_PROVIDERS, mangaProviders, INFORMATION_PROVIDERS, infoProviders, META_PROVIDERS, metaProviders, BASE_PROVIDERS, baseProviders }; diff --git a/anify-backend-recode/src/types/enums.ts b/anify-backend-recode/src/types/enums.ts index 370f45a..13ac6c7 100644 --- a/anify-backend-recode/src/types/enums.ts +++ b/anify-backend-recode/src/types/enums.ts @@ -8,6 +8,7 @@ export const enum ProviderType { MANGA = "MANGA", META = "META", INFORMATION = "INFORMATION", + BASE = "BASE", } export const enum Format { diff --git a/anify-backend-recode/src/types/types.ts b/anify-backend-recode/src/types/types.ts index 485c66a..e57b285 100644 --- a/anify-backend-recode/src/types/types.ts +++ b/anify-backend-recode/src/types/types.ts @@ -21,16 +21,8 @@ export type Anime = { duration: number | null; color: string | null; year: number | null; - rating: { - anilist: number; - mal: number; - kitsu: number; - }; - popularity: { - anilist: number; - mal: number; - kitsu: number; - }; + rating: { [key: string]: number } | null; + popularity: { [key: string]: number } | null; averageRating?: number; averagePopularity?: number; type: Type; @@ -69,16 +61,8 @@ export type Manga = { totalVolumes: number | null; color: string | null; year: number | null; - rating: { - anilist: number; - mal: number; - kitsu: number; - }; - popularity: { - anilist: number; - mal: number; - kitsu: number; - }; + rating: { [key: string]: number } | null; + popularity: { [key: string]: number } | null; averageRating?: number; averagePopularity?: number; genres: Genres[]; @@ -99,12 +83,12 @@ export type Manga = { characters: Character[]; }; -export type AnimeInfo = Pick & { +export type AnimeInfo = Pick & { rating: number | null; popularity: number | null; }; -export type MangaInfo = Pick & { +export type MangaInfo = Pick & { rating: number | null; popularity: number | null; }; From ff88e5b1a5e631701325e559fd2bf41335d9374e Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 6 Sep 2023 08:30:23 -0400 Subject: [PATCH 06/77] Bug fixes and mappings updates --- anify-backend-recode/db.sqlite | Bin 36864 -> 40960 bytes .../src/database/impl/create.ts | 10 +---- .../src/database/impl/delete.ts | 22 +++++++++ anify-backend-recode/src/database/impl/get.ts | 42 +++++++++++++++++- anify-backend-recode/src/index.ts | 29 ++++++++++-- anify-backend-recode/src/lib/impl/mappings.ts | 29 +++++++++++- anify-backend-recode/src/worker/impl/entry.ts | 15 +++++++ .../src/worker/impl/mappings.ts | 14 ++++++ anify-backend-recode/src/worker/index.ts | 7 +++ 9 files changed, 152 insertions(+), 16 deletions(-) create mode 100644 anify-backend-recode/src/database/impl/delete.ts create mode 100644 anify-backend-recode/src/worker/impl/entry.ts create mode 100644 anify-backend-recode/src/worker/impl/mappings.ts create mode 100644 anify-backend-recode/src/worker/index.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index f96a0e996b90eba38434718ff9f7d6500ca15b86..47012daee374aa926668c9afa7e923911025a5e0 100644 GIT binary patch literal 40960 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 E0soJ}xBvhE delta 31 ncmZoTz|^pSX@WE>3j+fK=R^g2MwX2UOZYdl82pJ}6rcbAibDx6 diff --git a/anify-backend-recode/src/database/impl/create.ts b/anify-backend-recode/src/database/impl/create.ts index b870d48..d2f325e 100644 --- a/anify-backend-recode/src/database/impl/create.ts +++ b/anify-backend-recode/src/database/impl/create.ts @@ -113,12 +113,6 @@ export const create = async (data: Anime | Manga) => { }); } - const insert = db.prepare(query); - - return new Promise((resolve, reject) => { - db.transaction(() => { - insert.run(params); - resolve(true); - }); - }); + const insert = await db.prepare(query).run(params); + return insert; }; diff --git a/anify-backend-recode/src/database/impl/delete.ts b/anify-backend-recode/src/database/impl/delete.ts new file mode 100644 index 0000000..a37be7e --- /dev/null +++ b/anify-backend-recode/src/database/impl/delete.ts @@ -0,0 +1,22 @@ +import { db } from ".."; +import { Anime, Manga } from "../../types/types"; + +export const deleteEntry = async (id: string): Promise => { + const anime = await db.query(`SELECT * FROM anime WHERE id = $id`).get({ $id: id }); + if (!anime) { + const data = (await db.query(`SELECT * FROM manga WHERE id = $id`).get({ $id: id })) as Manga | undefined; + if (!data) return undefined; + + try { + await db.query(`DELETE FROM manga WHERE id = $id`).run({ $id: id }); + } catch (e) { + return undefined; + } + } else { + try { + await db.query(`DELETE FROM anime WHERE id = $id`).run({ $id: id }); + } catch (e) { + return undefined; + } + } +}; diff --git a/anify-backend-recode/src/database/impl/get.ts b/anify-backend-recode/src/database/impl/get.ts index c7f4a04..f134c35 100644 --- a/anify-backend-recode/src/database/impl/get.ts +++ b/anify-backend-recode/src/database/impl/get.ts @@ -4,8 +4,46 @@ import { Anime, Manga } from "../../types/types"; export const get = async (id: string): Promise => { const anime = await db.query(`SELECT * FROM anime WHERE id = $id`).get({ $id: id }); if (!anime) { - return (await db.query(`SELECT * FROM manga WHERE id = $id`).get({ $id: id })) as Manga | undefined; + const data = (await db.query(`SELECT * FROM manga WHERE id = $id`).get({ $id: id })) as Manga | undefined; + if (!data) return undefined; + + try { + Object.assign(data, { + title: JSON.parse((data as any).title), + mappings: JSON.parse((data as any).mappings), + synonyms: JSON.parse((data as any).synonyms), + rating: JSON.parse((data as any).rating), + popularity: JSON.parse((data as any).popularity), + relations: JSON.parse((data as any).relations), + genres: JSON.parse((data as any).genres), + tags: JSON.parse((data as any).tags), + chapters: JSON.parse((data as any).chapters), + artwork: JSON.parse((data as any).artwork), + characters: JSON.parse((data as any).characters), + }); + + return data as Manga; + } catch (e) { + return undefined; + } } else { - return anime as Anime; + try { + Object.assign(anime, { + title: JSON.parse((anime as any).title), + mappings: JSON.parse((anime as any).mappings), + synonyms: JSON.parse((data as any).synonyms), + rating: JSON.parse((anime as any).rating), + popularity: JSON.parse((anime as any).popularity), + relations: JSON.parse((anime as any).relations), + genres: JSON.parse((anime as any).genres), + tags: JSON.parse((anime as any).tags), + episodes: JSON.parse((anime as any).episodes), + artwork: JSON.parse((anime as any).artwork), + characters: JSON.parse((anime as any).characters), + }); + return anime as Anime; + } catch (e) { + return undefined; + } } }; diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 537b436..9243b2a 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -3,9 +3,30 @@ dotenv.config(); import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; import { loadMapping } from "./lib/impl/mappings"; -import { Type } from "./types/enums"; +import { MediaStatus, Type } from "./types/enums"; +import { init } from "./database"; +import emitter, { Events } from "./lib"; +import { get } from "./database/impl/get"; +import queues from "./worker"; +import { deleteEntry } from "./database/impl/delete"; -fetchCorsProxies().then(async (_) => { - const data = await loadMapping({ id: "21", type: Type.ANIME }); - console.log(data); +before().then(async (_) => { + await loadMapping({ id: "142598", type: Type.ANIME }).then(console.log); }); + +async function before() { + await fetchCorsProxies(); + await init(); + + emitter.on(Events.COMPLETED_MAPPING_LOAD, async (data) => { + for (let i = 0; i < data.length; i++) { + if (await get(String(data[i].id))) { + continue; + } + queues.createEntry.add({ toInsert: data[i], type: data[i].type }); + } + }); + + queues.mappingQueue.start(); + queues.createEntry.start(); +} diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend-recode/src/lib/impl/mappings.ts index bda1594..8e18ddf 100644 --- a/anify-backend-recode/src/lib/impl/mappings.ts +++ b/anify-backend-recode/src/lib/impl/mappings.ts @@ -6,14 +6,28 @@ import { Format, MediaStatus, ProviderType, Season, Type } from "../../types/enu import { ANIME_PROVIDERS, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, animeProviders, baseProviders, infoProviders, mangaProviders, metaProviders } from "../../mappings"; import { clean, slugify } from "../../helper/title"; import { findBestMatch2DArray, similarity } from "../../helper/stringSimilarity"; -import { isString } from "../../helper"; +import { averageMetric, isString } from "../../helper"; import InformationProvider from "../../mappings/impl/information"; +import { deleteEntry } from "../../database/impl/delete"; export const loadMapping = async (data: { id: string; type: Type }, aniData?: AnimeInfo | MangaInfo | null, retries = 0, media?: Anime | Manga): Promise => { const MIN_MAPPINGS = 3; const MAX_RETRIES = 2; - if (retries > 0) console.log(colors.yellow("Remapping ") + colors.blue(data.id) + colors.yellow(" with retry ") + colors.blue(retries + "") + colors.yellow("...")); + if (retries > 0) { + console.log(colors.yellow("Remapping ") + colors.blue(data.id) + colors.yellow(" with retry ") + colors.blue(retries + "") + colors.yellow("...")); + // Delete entry if exists + try { + const existing = await get(data.id); + + if (existing) { + await deleteEntry(data.id); + } + } catch (e) { + console.error(e); + console.log(colors.red("Error while deleting from database.")); + } + } if (!aniData) { try { @@ -35,6 +49,7 @@ export const loadMapping = async (data: { id: string; type: Type }, aniData?: An // Map only one media if (!aniData) { + // TODO: If manga, use base provider for manga. Otherwise, use one for anime. aniData = await baseProviders.anilist.getMedia(data.id); } @@ -416,6 +431,16 @@ function fillMediaInfo } } + // Set averagePopularity and averageRating + if (media.rating) { + const averageRating = averageMetric(media.rating); + media.averageRating = averageRating; + } + if (media.popularity) { + const averagePopularity = averageMetric(media.popularity); + media.averagePopularity = averagePopularity; + } + return media; } catch (e) { console.log(colors.red(`Error while filling media info for ${media.id} with provider ${provider.id}`)); diff --git a/anify-backend-recode/src/worker/impl/entry.ts b/anify-backend-recode/src/worker/impl/entry.ts new file mode 100644 index 0000000..a07cdc5 --- /dev/null +++ b/anify-backend-recode/src/worker/impl/entry.ts @@ -0,0 +1,15 @@ +import QueueExecutor from "../../lib/executor"; +import { createEntry } from "../../lib/impl/entry"; +import colors from "colors"; +import { Anime, Manga } from "../../types/types"; +import { Type } from "../../types/enums"; + +const executor = new QueueExecutor<{ toInsert: Anime | Manga; type: Type }>("entry-executor") + .executor(async (data) => { + const media = await createEntry(data); + return media; + }) + .callback((id) => console.debug(colors.green(`Finished creating entry for media ${id.toInsert.title.english ?? id.toInsert.title.romaji ?? id.toInsert.title.native}`))) + .error((err, id) => console.error(colors.red(`Error occurred while creating entry for media ${id.toInsert.title.english ?? id.toInsert.title.romaji ?? id.toInsert.title.native}`), err)) + .interval(500); +export default executor; diff --git a/anify-backend-recode/src/worker/impl/mappings.ts b/anify-backend-recode/src/worker/impl/mappings.ts new file mode 100644 index 0000000..b956567 --- /dev/null +++ b/anify-backend-recode/src/worker/impl/mappings.ts @@ -0,0 +1,14 @@ +import QueueExecutor from "../../lib/executor"; +import { loadMapping } from "../../lib/impl/mappings"; +import colors from "colors"; +import { Type } from "../../types/enums"; + +const executor = new QueueExecutor<{ id: string; type: Type }>("mapping-executor") + .executor(async (data) => { + const media = await loadMapping(data); + return media; + }) + .callback((id) => console.debug(colors.green(`Finished mapping for media ${id.id}`))) + .error((err, id) => console.error(colors.red(`Error occurred while mapping for media ${id.id}`), err)) + .interval(1000); +export default executor; diff --git a/anify-backend-recode/src/worker/index.ts b/anify-backend-recode/src/worker/index.ts new file mode 100644 index 0000000..e916c08 --- /dev/null +++ b/anify-backend-recode/src/worker/index.ts @@ -0,0 +1,7 @@ +import mappingQueue from "./impl/mappings"; +import createEntry from "./impl/entry"; + +export default { + mappingQueue, + createEntry, +}; From 11507d51d6060a9b2cf402f68202bd0e231f8119 Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 6 Sep 2023 09:23:05 -0400 Subject: [PATCH 07/77] Bug fixes with SQLite --- anify-backend-recode/db.sqlite | Bin 40960 -> 40960 bytes .../src/database/impl/create.ts | 3 + .../src/database/impl/seasonal.ts | 4 +- anify-backend-recode/src/database/index.ts | 20 +- anify-backend-recode/src/index.ts | 3 +- .../src/mappings/impl/anime/gogoanime.ts | 131 ++++++ .../src/mappings/impl/anime/zoro.ts | 163 ++++++++ .../src/mappings/impl/information/anilist.ts | 8 +- .../src/mappings/impl/information/kitsu.ts | 109 +++++ .../src/mappings/impl/meta/anilist.ts | 393 ++++++++++++++++++ anify-backend-recode/src/mappings/index.ts | 10 +- 11 files changed, 825 insertions(+), 19 deletions(-) create mode 100644 anify-backend-recode/src/mappings/impl/anime/gogoanime.ts create mode 100644 anify-backend-recode/src/mappings/impl/anime/zoro.ts create mode 100644 anify-backend-recode/src/mappings/impl/information/kitsu.ts create mode 100644 anify-backend-recode/src/mappings/impl/meta/anilist.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 47012daee374aa926668c9afa7e923911025a5e0..e66d6a63d1f3fbca22766cdef0a38994f18ececa 100644 GIT binary patch delta 462 zcmZoTz|?SnX@az%00RR97ZAe$$3z`tSpf#Ucv)VKQw$u;QyDlUIHt3Uu)pTv;Xlhf zmHXz#MoDI=wi<4BadC0R-tdydq@2{;#Ju!GFu^+c3CDrS^Z0o=iYxQ-^D1+TC-?Kq zPM*X2aq<*?@ySQH>?Tj(mu4wROb1EGPgdi8zgdKR8zT!33p4-5Ms8*%O`gf;`DNt6 zro|hADK7pW3>+XAw%c)nt?i56?8T$Yh})j&e9Fl7$V|S?_nDCkXt0Jb3(y>}VZ1;F zBbONim)T}P0Ua)()%J{(@vQ7L9or0UIr0tk&k`qf()ANfe_45+*5=)9p zb@TFda}%>u^K{b_b&E4HGZHg(i%W}2m2{K}it@`cQ&NjOQ4{*1W%7FF15DMmlM7iySVCMQ zLMCVN{+T?V)k7S_(cw~nf|A7aVg<0g1lu1bO_s^$`DMhxCd3k6Yl=N)0Zq((K zmu=!_Xwlv5A!WxjIY-uGliYtsMy^E$3X2j976m9w3}D&JqVSQK-PqXN#K6pK^B-jv F9snKaQ{?~v diff --git a/anify-backend-recode/src/database/impl/create.ts b/anify-backend-recode/src/database/impl/create.ts index d2f325e..52380c2 100644 --- a/anify-backend-recode/src/database/impl/create.ts +++ b/anify-backend-recode/src/database/impl/create.ts @@ -2,8 +2,11 @@ import { db } from ".."; import { averageMetric } from "../../helper"; import { Type } from "../../types/enums"; import { Anime, Manga } from "../../types/types"; +import { get } from "./get"; export const create = async (data: Anime | Manga) => { + if (await get(data.id)) return console.log("Yeah no it exists lol"); + const query = ` INSERT INTO ${data.type === "ANIME" ? "anime" : "manga"} ( id, diff --git a/anify-backend-recode/src/database/impl/seasonal.ts b/anify-backend-recode/src/database/impl/seasonal.ts index f1a2f50..40579bf 100644 --- a/anify-backend-recode/src/database/impl/seasonal.ts +++ b/anify-backend-recode/src/database/impl/seasonal.ts @@ -1,8 +1,8 @@ import { db } from ".."; import { Type } from "../../types/enums"; -import { Anime, Manga } from "../../types/types"; +import { Anime, AnimeInfo, Manga, MangaInfo } from "../../types/types"; -export const seasonal = async (trending: Anime[] | Manga[], popular: Anime[] | Manga[], top: Anime[] | Manga[], seasonal: Anime[] | Manga[]) => { +export const seasonal = async (trending: AnimeInfo[] | MangaInfo[], popular: AnimeInfo[] | MangaInfo[], top: AnimeInfo[] | MangaInfo[], seasonal: AnimeInfo[] | MangaInfo[]) => { const ids = { trending: trending.map((a) => String(a.id)), popular: popular.map((a) => String(a.id)), diff --git a/anify-backend-recode/src/database/index.ts b/anify-backend-recode/src/database/index.ts index 216729e..f3e093b 100644 --- a/anify-backend-recode/src/database/index.ts +++ b/anify-backend-recode/src/database/index.ts @@ -14,8 +14,8 @@ export const init = async () => { season TEXT DEFAULT 'UNKNOWN', title JSON, currentEpisode INTEGER, - mappings JSON DEFAULT '{}', - synonyms TEXT, + mappings JSON DEFAULT '[]', + synonyms JSON DEFAULT '[]', countryOfOrigin TEXT, description TEXT, duration INTEGER, @@ -25,10 +25,10 @@ export const init = async () => { popularity JSON, type TEXT, format TEXT DEFAULT 'UNKNOWN', - relations JSON, + relations JSON DEFAULT '[]', totalEpisodes REAL, - genres TEXT, - tags TEXT, + genres JSON DEFAULT '[]', + tags JSON DEFAULT '[]', episodes JSON DEFAULT '{"latest": {"updatedAt": 0, "latestEpisode": 0, "latestTitle": ""}, "data": []}', averageRating REAL, averagePopularity REAL, @@ -45,8 +45,8 @@ export const init = async () => { bannerImage TEXT, status TEXT, title JSON, - mappings JSON DEFAULT '{}', - synonyms TEXT, + mappings JSON DEFAULT '[]', + synonyms JSON DEFAULT '[]', countryOfOrigin TEXT, description TEXT, duration INTEGER, @@ -56,11 +56,11 @@ export const init = async () => { popularity JSON, type TEXT, format TEXT DEFAULT 'UNKNOWN', - relations JSON, + relations JSON DEFAULT '[]', totalChapters REAL, totalVolumes REAL, - genres TEXT, - tags TEXT, + genres JSON DEFAULT '[]', + tags JSON DEFAULT '[]', chapters JSON DEFAULT '{"latest": {"updatedAt": 0, "latestChapter": 0, "latestTitle": ""}, "data": []}', averageRating REAL, averagePopularity REAL, diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 9243b2a..1bb38b6 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -3,12 +3,11 @@ dotenv.config(); import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; import { loadMapping } from "./lib/impl/mappings"; -import { MediaStatus, Type } from "./types/enums"; +import { Type } from "./types/enums"; import { init } from "./database"; import emitter, { Events } from "./lib"; import { get } from "./database/impl/get"; import queues from "./worker"; -import { deleteEntry } from "./database/impl/delete"; before().then(async (_) => { await loadMapping({ id: "142598", type: Type.ANIME }).then(console.log); diff --git a/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts b/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts new file mode 100644 index 0000000..e429d0a --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts @@ -0,0 +1,131 @@ +import { load } from "cheerio"; +import Extractor from "../../../helper/extractor"; +import AnimeProvider from "."; +import { Format, StreamingServers, SubType } from "../../../types/enums"; +import { Episode, Result, Source } from "../../../types/types"; + +export default class GogoAnime extends AnimeProvider { + override rateLimit = 250; + override id = "gogoanime"; + override url = "https://gogoanimehd.io"; + + override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; + + override get subTypes(): SubType[] { + return [SubType.SUB, SubType.DUB]; + } + + override get headers(): Record | undefined { + return undefined; + } + + override async search(query: string, format?: Format, year?: number): Promise { + const request = await this.request(`${this.url}/search.html?keyword=${encodeURIComponent(query)}`); + if (!request.ok) { + return []; + } + const data = await request.text(); + const results: Result[] = []; + + const $ = load(data); + + $("ul.items > li").map((i, el) => { + const title = $("p.name a", el).text().trim(); + const id = $(el).find("div.img a").attr("href")!; + const releasedText = $("p.released", el).text().trim(); + const yearMatch = releasedText.match(/Released:\s+(\d{4})/); + const year = yearMatch ? parseInt(yearMatch[1]) : 0; + const img = $(el).find("div.img a img").attr("src")!; + + const format: Format = Format.UNKNOWN; + + results.push({ + id: id, + title: title, + altTitles: [], + img: img, + format, + year: year, + providerId: this.id, + }); + }); + + return results; + } + + override async fetchEpisodes(id: string): Promise { + const episodes: Episode[] = []; + + const data = await (await this.request(`${this.url}${id}`)).text(); + + const $ = load(data); + + const epStart = $("#episode_page > li").first().find("a").attr("ep_start"); + const epEnd = $("#episode_page > li").last().find("a").attr("ep_end"); + const movieId = $("#movie_id").attr("value"); + const alias = $("#alias_anime").attr("value"); + + const req = await (await this.request(`https://ajax.gogo-load.com/ajax/load-list-episode?ep_start=${epStart}&ep_end=${epEnd}&id=${movieId}&default_ep=${0}&alias=${alias}`)).text(); + + const $$ = load(req); + + $$("#episode_related > li").each((i, el) => { + episodes?.push({ + id: $(el).find("a").attr("href")?.trim()!, + number: parseFloat($(el).find(`div.name`).text().replace("EP ", "")), + title: $(el).find(`div.name`).text(), + isFiller: false, + img: null, + hasDub: id.includes("-dub"), + }); + }); + return episodes; + } + + override async fetchSources(id: string, subType = SubType.SUB, server: StreamingServers = StreamingServers.GogoCDN): Promise { + const result: Source = { + sources: [], + subtitles: [], + audio: [], + intro: { + start: 0, + end: 0, + }, + outro: { + start: 0, + end: 0, + }, + headers: this.headers ?? {}, + }; + + if (id.startsWith("http")) { + const serverURL = id; + const download = `https://gogohd.net/download${new URL(serverURL).search}`; + + return await new Extractor(serverURL, result).extract(server); + } + + const data = await (await this.request(`${this.url}${id}`)).text(); + + const $ = load(data); + + let serverURL: string; + + switch (server) { + case StreamingServers.GogoCDN: + serverURL = `${$("#load_anime > div > div > iframe").attr("src")}`; + break; + case StreamingServers.VidStreaming: + serverURL = `${$("div.anime_video_body > div.anime_muti_link > ul > li.vidcdn > a").attr("data-video")}`; + break; + case StreamingServers.StreamSB: + serverURL = $("div.anime_video_body > div.anime_muti_link > ul > li.streamsb > a").attr("data-video")!; + break; + default: + serverURL = `${$("#load_anime > div > div > iframe").attr("src")}`; + break; + } + + return await this.fetchSources(serverURL, subType, server); + } +} diff --git a/anify-backend-recode/src/mappings/impl/anime/zoro.ts b/anify-backend-recode/src/mappings/impl/anime/zoro.ts new file mode 100644 index 0000000..94d0bb8 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/anime/zoro.ts @@ -0,0 +1,163 @@ +import { load } from "cheerio"; +import Extractor from "../../../helper/extractor"; +import AnimeProvider from "."; +import { Format, Formats, StreamingServers, SubType } from "../../../types/enums"; +import { Episode, Result, Source } from "../../../types/types"; + +export default class Zoro extends AnimeProvider { + override rateLimit = 250; + override id = "zoro"; + //override url = "https://zoro.to"; + override url = "http://aniwatch.to"; + + override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; + + override get subTypes(): SubType[] { + return [SubType.SUB, SubType.DUB]; + } + + override get headers(): Record | undefined { + return undefined; + } + + override async search(query: string, format?: Format, year?: number): Promise { + const data = await (await this.request(`${this.url}/search?keyword=${encodeURIComponent(query)}`)).text(); + const results: Result[] = []; + + const $ = load(data); + + $(".film_list-wrap > div.flw-item").map((i, el) => { + const title = $(el).find("div.film-detail h3.film-name a.dynamic-name").attr("title")!.trim().replace(/\\n/g, ""); + const id = $(el).find("div:nth-child(1) > a").last().attr("href")!; + const img = $(el).find("img").attr("data-src")!; + + const altTitles: string[] = []; + const jpName = $(el).find("div.film-detail h3.film-name a.dynamic-name").attr("data-jname")!.trim().replace(/\\n/g, ""); + altTitles.push(jpName); + + const formatString: string = $(el).find("div.film-detail div.fd-infor span.fdi-item")?.first()?.text().toUpperCase(); + const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + results.push({ + id: id, + title: title, + altTitles: altTitles, + year: 0, + format, + img: img, + providerId: this.id, + }); + }); + + return results; + } + + override async fetchEpisodes(id: string): Promise { + const episodes: Episode[] = []; + + const data = await ( + await this.request(`${this.url}/ajax/v2/episode/list/${id.split("-").pop()}`, { + headers: { + "X-Requested-With": "XMLHttpRequest", + Referer: `${this.url}/watch/${id}`, + }, + }) + ).json(); + + const $ = load(data.html); + + const hasDubCheck = await (await this.request(`${this.url}/watch${id}`)).text(); + const $$ = load(hasDubCheck); + + const subDub = $$("div.film-stats div.tick-dub") + .toArray() + .map((value) => $$(value).text().toLowerCase()); + const dubCount = subDub.length >= 1 ? parseInt(subDub[0]) : false; + + $("div.detail-infor-content > div > a").map((i, el) => { + const number = parseInt($(el).attr("data-number")!); + const title = $(el).attr("title")!; + const id = $(el).attr("href")!; + const isFiller = $(el).hasClass("ssl-item-filler")!; + + episodes.push({ + id, + isFiller, + number, + title, + img: null, + hasDub: dubCount ? number <= dubCount : false, + }); + }); + + return episodes; + } + + override async fetchSources(id: string, subType: SubType = SubType.SUB, server: StreamingServers = StreamingServers.VidCloud): Promise { + const result: Source = { + sources: [], + subtitles: [], + audio: [], + intro: { + start: 0, + end: 0, + }, + outro: { + start: 0, + end: 0, + }, + headers: this.headers ?? {}, + }; + + if (id.startsWith("http")) { + const serverURL = id; + + return await new Extractor(serverURL, result).extract(server); + } + + const data = await (await this.request(`${this.url}/ajax/v2/episode/servers?episodeId=${id.split("?ep=")[1]}`)).json(); + const $ = load(data.html); + + /** + * vidtreaming -> 4 + * rapidcloud -> 1 + * streamsb -> 5 + * streamtape -> 3 + */ + let serverId; + switch (server) { + case StreamingServers.VidCloud: + serverId = this.retrieveServerId($, 4, subType); + + if (!serverId) throw new Error("RapidCloud not found"); + break; + case StreamingServers.VidStreaming: + serverId = this.retrieveServerId($, 4, subType); + + if (!serverId) throw new Error("VidStreaming not found"); + break; + case StreamingServers.StreamSB: + serverId = this.retrieveServerId($, 5, subType); + + if (!serverId) throw new Error("StreamSB not found"); + break; + case StreamingServers.StreamTape: + serverId = this.retrieveServerId($, 3, subType); + + if (!serverId) throw new Error("StreamTape not found"); + break; + default: + throw new Error("Server not found"); + } + + const req = await (await this.request(`${this.url}/ajax/v2/episode/sources?id=${serverId}`)).json(); + return await this.fetchSources(req.link, subType, server); + } + + private retrieveServerId($: any, index: number, subOrDub: SubType) { + return $(`div.ps_-block.ps_-block-sub.servers-${subOrDub} > div.ps__-list > div`) + .map((i: any, el: any) => ($(el).attr("data-server-id") === `${index}` ? $(el) : null)) + .get()[0] + ?.attr("data-id")!; + } +} diff --git a/anify-backend-recode/src/mappings/impl/information/anilist.ts b/anify-backend-recode/src/mappings/impl/information/anilist.ts index 76fd7d8..59f4b7b 100644 --- a/anify-backend-recode/src/mappings/impl/information/anilist.ts +++ b/anify-backend-recode/src/mappings/impl/information/anilist.ts @@ -120,7 +120,7 @@ export default class AniList extends InformationProvider { - const anilistId = media.id; + const anilistId = media.mappings.find((data) => { + return data.providerId === "anilist"; + })?.id; + + if (!anilistId) return undefined; const query = `query ($id: Int) { Media (id: $id) { diff --git a/anify-backend-recode/src/mappings/impl/information/kitsu.ts b/anify-backend-recode/src/mappings/impl/information/kitsu.ts new file mode 100644 index 0000000..b144c83 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/information/kitsu.ts @@ -0,0 +1,109 @@ +import InformationProvider from "."; +import { Format, Season } from "../../../types/enums"; +import { Anime, AnimeInfo, Artwork, Manga, MangaInfo, MediaInfoKeys } from "../../../types/types"; + +export default class Kitsu extends InformationProvider { + override id = "kitsu"; + override url = "https://kitsu.io"; + + private kitsuApiUrl = "https://kitsu.io/api/edge"; + + override get priorityArea(): MediaInfoKeys[] { + return ["coverImage"]; + } + + override get sharedArea(): MediaInfoKeys[] { + return ["synonyms", "genres", "artwork"]; + } + + override async info(media: Anime | Manga): Promise { + const kitsuId = media.mappings.find((data) => { + return data.providerId === "kitsu"; + })?.id; + + if (!kitsuId) return undefined; + + const kitsuResponse: KitsuResponse = await (await this.request(`${this.kitsuApiUrl}/${media.type.toLowerCase()}/${kitsuId}`, {}, true)).json(); + + const attributes = kitsuResponse?.data?.attributes; + + if (!attributes) return undefined; + + const kitsuGenre = await (await this.request(`${this.kitsuApiUrl}/${media.type.toLowerCase()}/${kitsuId}/genres`, {}, true)).json(); + const genres = kitsuGenre?.data; + + const artwork: Artwork[] = []; + + if (attributes.coverImage?.original) + artwork.push({ + type: "banner", + img: attributes.coverImage.original, + providerId: this.id, + }); + if (attributes.posterImage?.original) + artwork.push({ + type: "poster", + img: attributes.posterImage.original, + providerId: this.id, + }); + + return { + id: kitsuId, + title: { + english: attributes.titles.en ?? null, + romaji: attributes.titles.en_jp ?? null, + native: attributes.titles.ja_jp ?? null, + }, + currentEpisode: null, + trailer: null, + duration: attributes.episodeLength ?? null, + color: null, + bannerImage: attributes.coverImage?.original ?? null, + coverImage: attributes.posterImage?.original ?? null, + status: null, + format: Format.UNKNOWN, + season: Season.UNKNOWN, + synonyms: [], + description: attributes.synopsis ?? null, + year: null, + totalEpisodes: attributes.episodeCount ?? 0, + genres: genres ? genres.map((genre: any) => genre.attributes.name) : [], + rating: attributes.averageRating ? Number.parseFloat((Number.parseFloat(attributes.averageRating) / 10).toFixed(2)) : null, + popularity: null, + countryOfOrigin: null, + tags: [], + relations: [], + artwork, + characters: [], + totalChapters: null, + totalVolumes: null, + type: media.type, + }; + } +} + +type KitsuResponse = { + data: { + attributes: { + titles: { + en: string | null; + en_jp: string | null; + ja_jp: string | null; + }; + description: string | null; + subtype: string; + status: string; + showType: string; + synopsis: string | null; + episodeLength: number | null; + posterImage: { + original: string | null; + }; + coverImage: { + original: string | null; + }; + averageRating: string | null; + episodeCount: number | null; + }; + }; +}; diff --git a/anify-backend-recode/src/mappings/impl/meta/anilist.ts b/anify-backend-recode/src/mappings/impl/meta/anilist.ts new file mode 100644 index 0000000..2f2f3b5 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/meta/anilist.ts @@ -0,0 +1,393 @@ +import MetaProvider from "."; +import { Format, Type } from "../../../types/enums"; +import { Result } from "../../../types/types"; + +export default class AniListMeta extends MetaProvider { + override id = "anilist"; + override url = "https://anilist.co"; + + override rateLimit = 500; + override formats: Format[] = [Format.TV, Format.MOVIE, Format.ONA, Format.SPECIAL, Format.TV_SHORT, Format.OVA, Format.MANGA, Format.ONE_SHOT, Format.NOVEL]; + + private api = "https://graphql.anilist.co"; + + override async search(query: string, format?: Format, year?: number): Promise { + const results: Result[] = []; + + const aniListArgs = { + query: ` + query($page: Int, $perPage: Int, $search: String, $format: [MediaFormat]) { + Page(page: $page, perPage: $perPage) { + pageInfo { + total + currentPage + lastPage + hasNextPage + perPage + } + media(format_in: $format, search: $search) { + ${this.query} + } + } + } + `, + variables: { + search: query, + format: format ? [format] : null, + page: 0, + perPage: 15, + }, + }; + const req = await this.request( + this.api, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + origin: "graphql.anilist.co", + }, + body: JSON.stringify(aniListArgs), + }, + true, + ); + const json = await req?.json(); + const media = json.data.Page.media; + + media.map((data: Media) => { + results.push({ + id: String(data.id), + altTitles: data.synonyms.concat(Object.values(data.title)), + title: data.title.english ?? data.title.romaji ?? data.title.native, + format: data.format, + img: data.coverImage.extraLarge, + providerId: this.id, + year: data.seasonYear ?? data.startDate.year ?? 0, + }); + }); + + return results; + } + + public async batchRequest(queries: string[], maxQueries: number): Promise { + const results: any[] = []; + + const processBatch = async (batch: string[]) => { + const currentQuery = `{${batch.join("\n")}}`; + const result = await this.executeGraphQLQuery(currentQuery); + if (result) { + const data = await result.json(); + results.push(...Object.values(data)); + } + }; + + const batchedQueries: string[][] = []; + for (let i = 0; i < queries.length; i += maxQueries) { + batchedQueries.push(queries.slice(i, i + maxQueries)); + } + + for await (const batch of batchedQueries) { + await processBatch(batch); + } + + return results; + } + + private async executeGraphQLQuery(query: string) { + const variables = {}; + return await this.request( + this.api, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + origin: "graphql.anilist.co", + }, + body: JSON.stringify({ + query, + variables, + }), + }, + true, + ).catch((err) => { + console.error(err); + return null; + }); + } + + public query = ` + id + idMal + title { + romaji + english + native + userPreferred + } + coverImage { + extraLarge + large + color + } + bannerImage + startDate { + year + month + day + } + endDate { + year + month + day + } + description + season + seasonYear + type + format + status(version: 2) + episodes + duration + chapters + volumes + genres + synonyms + source(version: 3) + isAdult + meanScore + averageScore + popularity + favourites + countryOfOrigin + isLicensed + characters { + edges { + voiceActors { + id + name { + first + middle + last + full + native + } + image { + large + } + gender + age + dateOfBirth { + year + month + day + } + languageV2 + } + role + node { + id + name { + first + middle + last + full + native + alternative + alternativeSpoiler + } + age + image { + large + } + description + modNotes + siteUrl + } + } + } + relations { + edges { + id + relationType(version: 2) + node { + id + title { + english + romaji + native + } + format + type + status(version: 2) + bannerImage + coverImage { + large + } + } + } + } + streamingEpisodes { + title + thumbnail + url + } + trailer { + id + site + } + tags { + id + name + } + `; +} + +interface Media { + id: number; + idMal: number; + title: { + english?: string; + romaji: string; + native: string; + userPreferred: string; + }; + coverImage: { + extraLarge: string; + large: string; + color?: string; + }; + bannerImage: string; + startDate: { + year: number; + month: number; + day: number; + }; + endDate: { + year: number; + month: number; + day: number; + }; + description: string; + season: "WINTER" | "SPRING" | "SUMMER" | "FALL"; + seasonYear: number; + type: Type; + format: Format; + status: "FINISHED" | "RELEASING" | "NOT_YET_RELEASED" | "CANCELLED"; + episodes?: number; + duration?: number; + chapters?: number; + volumes?: number; + genres: string[]; + synonyms: string[]; + source: "ORIGINAL" | "LIGHT_NOVEL" | "VISUAL_NOVEL" | "VIDEO_GAME" | "OTHER" | "NOVEL" | "MANGA" | "DOUJINSHI" | "ANIME" | "WEB_MANGA" | "BOOK" | "CARD_GAME" | "COMIC" | "GAME" | "MUSIC" | "NOVEL" | "ONE_SHOT" | "OTHER" | "PICTURE_BOOK" | "RADIO" | "TV" | "UNKNOWN"; + isAdult: boolean; + meanScore: number; + averageScore: number; + popularity: number; + favourites: number; + countryOfOrigin: string; + isLicensed: boolean; + airingSchedule: { + edges: { + node: { + airingAt?: any; + timeUntilAiring?: any; + episode?: any; + }; + }; + }; + relations: { + edges: [RelationsNode]; + }; + characters: { + edges: [ + { + role: string; + voiceActors: [ + { + id: number; + name: { + first: string; + middle: string; + last: string; + full: string; + native: string; + }; + languageV2: string; + image: { + large: string; + }; + gender: string | null; + age: number | null; + dateOfBirth: { + year: number | null; + month: number | null; + day: number | null; + }; + }, + ]; + node: { + id: number; + name: { + first: string; + middle: string; + last: string; + full: string; + native: string; + alternative: string[]; + alternativeSpoiler: string[]; + }; + age: number | null; + image: { + large: string; + }; + description: string; + modNotes: string; + siteUrl: string; + }; + }, + ]; + }; + studios: { + edges: { + isMain: boolean; + node: { + id: number; + name: string; + }; + }; + }; + streamingEpisodes: [ + { + title?: string; + thumbnail?: string; + url?: string; + }, + ]; + trailer: { + id: string; + site: string; + }; + tags: [{ id: number; name: string }]; +} + +interface RelationsNode { + id: number; + relationType: string; + node: { + id: number; + title: { + english: string | null; + romaji: string | null; + native: string | null; + }; + format: Format; + type: Type; + status: string; + bannerImage: string; + coverImage: { + large: string; + }; + }; +} diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend-recode/src/mappings/index.ts index a3142cd..fa32000 100644 --- a/anify-backend-recode/src/mappings/index.ts +++ b/anify-backend-recode/src/mappings/index.ts @@ -1,16 +1,20 @@ import { Anime, AnimeInfo, Manga, MangaInfo } from "../types/types"; import AnimeProvider from "./impl/anime"; import AnimePahe from "./impl/anime/animepahe"; +import GogoAnime from "./impl/anime/gogoanime"; import NineAnime from "./impl/anime/nineanime"; +import Zoro from "./impl/anime/zoro"; import BaseProvider from "./impl/base"; import AniListBase from "./impl/base/anilist"; import InformationProvider from "./impl/information"; import AniList from "./impl/information/anilist"; +import Kitsu from "./impl/information/kitsu"; import MangaProvider from "./impl/manga"; import MetaProvider from "./impl/meta"; +import AniListMeta from "./impl/meta/anilist"; import TheTVDB from "./impl/meta/tvdb"; -const ANIME_PROVIDERS: AnimeProvider[] = [new NineAnime(), new AnimePahe()]; +const ANIME_PROVIDERS: AnimeProvider[] = [new NineAnime(), new AnimePahe(), new GogoAnime(), new Zoro()]; const animeProviders: Record = ANIME_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; @@ -28,7 +32,7 @@ const mangaProviders: Record = MANGA_PROVIDERS.reduce( {} as Record, ); -const INFORMATION_PROVIDERS: InformationProvider[] = [new AniList()]; +const INFORMATION_PROVIDERS: InformationProvider[] = [new AniList(), new Kitsu()]; const infoProviders: Record> = INFORMATION_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; @@ -37,7 +41,7 @@ const infoProviders: Record>, ); -const META_PROVIDERS: MetaProvider[] = [new TheTVDB()]; +const META_PROVIDERS: MetaProvider[] = [new TheTVDB(), new AniListMeta()]; const metaProviders: Record = META_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; From f9612752d629023be2eb0bb68fb71b9e41dc50fe Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 6 Sep 2023 11:10:17 -0400 Subject: [PATCH 08/77] Updates to database --- anify-backend-recode/src/database/impl/get.ts | 2 +- .../src/database/impl/search.ts | 43 +++++- .../src/database/impl/searchAdvanced.ts | 43 +++++- .../src/database/impl/seasonal.ts | 120 +++++++++++++++++ anify-backend-recode/src/index.ts | 5 +- anify-backend-recode/src/lib/impl/entry.ts | 2 +- .../src/mappings/impl/information/mal.ts | 127 ++++++++++++++++++ .../src/mappings/impl/meta/mal.ts | 0 8 files changed, 334 insertions(+), 8 deletions(-) create mode 100644 anify-backend-recode/src/mappings/impl/information/mal.ts create mode 100644 anify-backend-recode/src/mappings/impl/meta/mal.ts diff --git a/anify-backend-recode/src/database/impl/get.ts b/anify-backend-recode/src/database/impl/get.ts index f134c35..ec4f72b 100644 --- a/anify-backend-recode/src/database/impl/get.ts +++ b/anify-backend-recode/src/database/impl/get.ts @@ -31,7 +31,7 @@ export const get = async (id: string): Promise => { Object.assign(anime, { title: JSON.parse((anime as any).title), mappings: JSON.parse((anime as any).mappings), - synonyms: JSON.parse((data as any).synonyms), + synonyms: JSON.parse((anime as any).synonyms), rating: JSON.parse((anime as any).rating), popularity: JSON.parse((anime as any).popularity), relations: JSON.parse((anime as any).relations), diff --git a/anify-backend-recode/src/database/impl/search.ts b/anify-backend-recode/src/database/impl/search.ts index 8fbee7f..40f3bcb 100644 --- a/anify-backend-recode/src/database/impl/search.ts +++ b/anify-backend-recode/src/database/impl/search.ts @@ -1,5 +1,6 @@ import { db } from ".."; import { Format, Type } from "../../types/enums"; +import { Anime, Manga } from "../../types/types"; export const search = async (query: string, type: Type, formats: Format[], page: number, perPage: number) => { const skip = page > 0 ? perPage * (page - 1) : 0; @@ -15,6 +16,44 @@ export const search = async (query: string, type: Type, formats: Format[], page: ${formats?.length > 0 ? `AND "format" IN (${formats.map((f) => `'${f}'`).join(", ")})` : ""} `; - const data = await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} ${where} ORDER BY title->>'english' ASC LIMIT ${perPage} OFFSET ${skip}`).all(); - return data; + const results = (await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} ${where} ORDER BY title->>'english' ASC LIMIT ${perPage} OFFSET ${skip}`).all()) as Anime[] | Manga[]; + return results.map((data) => { + try { + if (data.type === Type.ANIME) { + Object.assign(data, { + title: JSON.parse((data as any).title), + mappings: JSON.parse((data as any).mappings), + synonyms: JSON.parse((data as any).synonyms), + rating: JSON.parse((data as any).rating), + popularity: JSON.parse((data as any).popularity), + relations: JSON.parse((data as any).relations), + genres: JSON.parse((data as any).genres), + tags: JSON.parse((data as any).tags), + episodes: JSON.parse((data as any).episodes), + artwork: JSON.parse((data as any).artwork), + characters: JSON.parse((data as any).characters), + }); + + return data; + } else { + Object.assign(data, { + title: JSON.parse((data as any).title), + mappings: JSON.parse((data as any).mappings), + synonyms: JSON.parse((data as any).synonyms), + rating: JSON.parse((data as any).rating), + popularity: JSON.parse((data as any).popularity), + relations: JSON.parse((data as any).relations), + genres: JSON.parse((data as any).genres), + tags: JSON.parse((data as any).tags), + chapters: JSON.parse((data as any).chapters), + artwork: JSON.parse((data as any).artwork), + characters: JSON.parse((data as any).characters), + }); + + return data; + } + } catch (e) { + return undefined; + } + }); }; diff --git a/anify-backend-recode/src/database/impl/searchAdvanced.ts b/anify-backend-recode/src/database/impl/searchAdvanced.ts index 6b59dbc..3a66b43 100644 --- a/anify-backend-recode/src/database/impl/searchAdvanced.ts +++ b/anify-backend-recode/src/database/impl/searchAdvanced.ts @@ -1,5 +1,6 @@ import { db } from ".."; import { Format, Genres, Type } from "../../types/enums"; +import { Anime, Manga } from "../../types/types"; export const searchAdvanced = async (query: string, type: Type, formats: Format[], page: number, perPage: number, genres: Genres[] = [], genresExcluded: Genres[] = [], year = 0, tags: string[] = [], tagsExcluded: string[] = []) => { const skip = page > 0 ? perPage * (page - 1) : 0; @@ -59,6 +60,44 @@ export const searchAdvanced = async (query: string, type: Type, formats: Format[ where += `AND (${tagsWhere})`; } - const data = await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} ${where} ORDER BY title->>'english' ASC LIMIT ${perPage} OFFSET ${skip}`).all(); - return data; + const results = (await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} ${where} ORDER BY title->>'english' ASC LIMIT ${perPage} OFFSET ${skip}`).all()) as Anime[] | Manga[]; + return results.map((data) => { + try { + if (data.type === Type.ANIME) { + Object.assign(data, { + title: JSON.parse((data as any).title), + mappings: JSON.parse((data as any).mappings), + synonyms: JSON.parse((data as any).synonyms), + rating: JSON.parse((data as any).rating), + popularity: JSON.parse((data as any).popularity), + relations: JSON.parse((data as any).relations), + genres: JSON.parse((data as any).genres), + tags: JSON.parse((data as any).tags), + episodes: JSON.parse((data as any).episodes), + artwork: JSON.parse((data as any).artwork), + characters: JSON.parse((data as any).characters), + }); + + return data; + } else { + Object.assign(data, { + title: JSON.parse((data as any).title), + mappings: JSON.parse((data as any).mappings), + synonyms: JSON.parse((data as any).synonyms), + rating: JSON.parse((data as any).rating), + popularity: JSON.parse((data as any).popularity), + relations: JSON.parse((data as any).relations), + genres: JSON.parse((data as any).genres), + tags: JSON.parse((data as any).tags), + chapters: JSON.parse((data as any).chapters), + artwork: JSON.parse((data as any).artwork), + characters: JSON.parse((data as any).characters), + }); + + return data; + } + } catch (e) { + return undefined; + } + }); }; diff --git a/anify-backend-recode/src/database/impl/seasonal.ts b/anify-backend-recode/src/database/impl/seasonal.ts index 40579bf..23a7308 100644 --- a/anify-backend-recode/src/database/impl/seasonal.ts +++ b/anify-backend-recode/src/database/impl/seasonal.ts @@ -51,15 +51,135 @@ export const seasonal = async (trending: AnimeInfo[] | MangaInfo[], popular: Ani .all()) as Anime[] | Manga[]; trend.map((media) => { + if (media.type === Type.ANIME) { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + episodes: JSON.parse((media as any).episodes), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } else { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + chapters: JSON.parse((media as any).chapters), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } + media.characters = []; }); pop.map((media) => { + if (media.type === Type.ANIME) { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + episodes: JSON.parse((media as any).episodes), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } else { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + chapters: JSON.parse((media as any).chapters), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } + media.characters = []; }); t.map((media) => { + if (media.type === Type.ANIME) { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + episodes: JSON.parse((media as any).episodes), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } else { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + chapters: JSON.parse((media as any).chapters), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } + media.characters = []; }); season.map((media) => { + if (media.type === Type.ANIME) { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + episodes: JSON.parse((media as any).episodes), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } else { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + chapters: JSON.parse((media as any).chapters), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } + media.characters = []; }); diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 1bb38b6..30047df 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -3,14 +3,15 @@ dotenv.config(); import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; import { loadMapping } from "./lib/impl/mappings"; -import { Type } from "./types/enums"; +import { Format, Type } from "./types/enums"; import { init } from "./database"; import emitter, { Events } from "./lib"; import { get } from "./database/impl/get"; import queues from "./worker"; +import { search } from "./database/impl/search"; before().then(async (_) => { - await loadMapping({ id: "142598", type: Type.ANIME }).then(console.log); + await search("Seven", Type.ANIME, [Format.TV], 1, 10).then(console.log); }); async function before() { diff --git a/anify-backend-recode/src/lib/impl/entry.ts b/anify-backend-recode/src/lib/impl/entry.ts index cd6cc81..d5f6263 100644 --- a/anify-backend-recode/src/lib/impl/entry.ts +++ b/anify-backend-recode/src/lib/impl/entry.ts @@ -14,7 +14,7 @@ export const createEntry = async (data: { toInsert: Anime | Manga; type: Type }) if (data.type === Type.ANIME) { if (Array.isArray((data.toInsert as any).season)) { - (data.toInsert as any).season = (data.toInsert as any).season[0]; + (data.toInsert as any).season = String((data.toInsert as any).season[0]?.trim()); } } diff --git a/anify-backend-recode/src/mappings/impl/information/mal.ts b/anify-backend-recode/src/mappings/impl/information/mal.ts new file mode 100644 index 0000000..e1493ea --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/information/mal.ts @@ -0,0 +1,127 @@ +import InformationProvider from "."; +import { Format, Genres, MediaStatus, Season } from "../../../types/enums"; +import { Anime, AnimeInfo, Artwork, Manga, MangaInfo, MediaInfoKeys } from "../../../types/types"; + +export default class MAL extends InformationProvider { + override id = "mal"; + override url = "https://myanimelist.net"; + + override get priorityArea(): MediaInfoKeys[] { + return []; + } + + override get sharedArea(): MediaInfoKeys[] { + return ["synonyms", "genres", "artwork"]; + } + + override async info(media: Anime | Manga): Promise { + const malId = media.mappings.find((data) => { + return data.providerId === "mal"; + })?.id; + + if (!malId) return undefined; + + const req = await this.request(`https://api.jikan.moe/v4/${media.type.toLowerCase()}/${malId}/full`, { + headers: { + origin: "https://jikan.moe", + }, + }); + + if (!req.ok) return undefined; + const jikanResponse = await req.json(); + + const data: JikanResponse = jikanResponse.data; + + if (!data) return undefined; + + const artwork: Artwork[] = []; + + if (data.images?.jpg?.image_url) + artwork.push({ + type: "poster", + img: data.images.jpg.image_url, + providerId: this.id, + }); + + return { + id: String(data.mal_id), + title: { + english: data.title_english ?? null, + romaji: data.title ?? null, + native: data.title_japanese ?? null, + }, + currentEpisode: data.status === "completed" ? data.episodes : null, + trailer: data.trailer ? data.trailer.url : null, + coverImage: data.images?.jpg?.large_image_url ?? data.images?.jpg?.image_url ?? data.images?.jpg?.small_image_url ?? null, + bannerImage: null, + color: null, + totalEpisodes: data.episodes ?? 0, + status: data.status ? ((data.status as string).toLowerCase() === "not yet aired" ? MediaStatus.NOT_YET_RELEASED : (data.status as string).toLowerCase() === "currently airing" ? MediaStatus.RELEASING : (data.status as string).toLowerCase() === "finished airing" ? MediaStatus.FINISHED : null) : null, + popularity: data.popularity, + synonyms: data.title_synonyms?.filter((s) => s?.length) ?? [], + season: data.season ? ([(data.season as string).toUpperCase()] as unknown as Season) : Season.UNKNOWN, + genres: data.genres ? (data.genres.map((g) => g.name) as Genres[]) : [], + description: data.synopsis ?? null, + rating: data.score ?? null, + year: data.year ?? null, + duration: data.duration ? Number.parseInt(data.duration.replace("min per ep", "").trim()) : null, + format: data.type.toUpperCase() as Format, + countryOfOrigin: null, + tags: [], + relations: [], + artwork, + characters: [], + totalChapters: null, + totalVolumes: null, + type: media.type, + }; + } +} + +type JikanResponse = { + mal_id: number; + url: string; + title: string; + title_english: string | null; + title_japanese: string | null; + title_synonyms: string[]; + type: string; + status: string; + synopsis: string | null; + images: { + jpg: { + image_url: string | null; + small_image_url: string | null; + large_image_url: string | null; + }; + webp: { + image_url: string | null; + small_image_url: string | null; + large_image_url: string | null; + }; + }; + duration: string; + episodes: number | null; + popularity: number | null; + score: number | null; + season: string; + year: number | null; + genres: { name: string }[]; + trailer: { + youtube_id: string | null; + url: string | null; + embed_url: string | null; + images: { + image_url: string | null; + small_image_url: string | null; + medium_image_url: string | null; + large_image_url: string | null; + maximum_image_url: string | null; + }; + }; + approved: boolean; + titles: { + type: string; + title: string; + }[]; +}; diff --git a/anify-backend-recode/src/mappings/impl/meta/mal.ts b/anify-backend-recode/src/mappings/impl/meta/mal.ts new file mode 100644 index 0000000..e69de29 From f1134618554c4fbfa327f39f3106167db7b508bd Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 6 Sep 2023 12:44:34 -0400 Subject: [PATCH 09/77] Added a lot of providers --- anify-backend-recode/db.sqlite | Bin 40960 -> 57344 bytes anify-backend-recode/src/index.ts | 8 +- .../src/mappings/impl/information/anilist.ts | 19 +- .../src/mappings/impl/information/mal.ts | 14 +- .../src/mappings/impl/information/tvdb.ts | 194 ++++++++++++ .../src/mappings/impl/meta/kitsu.ts | 277 ++++++++++++++++++ .../src/mappings/impl/meta/mal.ts | 94 ++++++ .../src/mappings/impl/meta/tmdb.ts | 115 ++++++++ anify-backend-recode/src/mappings/index.ts | 9 +- 9 files changed, 713 insertions(+), 17 deletions(-) create mode 100644 anify-backend-recode/src/mappings/impl/information/tvdb.ts create mode 100644 anify-backend-recode/src/mappings/impl/meta/kitsu.ts create mode 100644 anify-backend-recode/src/mappings/impl/meta/tmdb.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index e66d6a63d1f3fbca22766cdef0a38994f18ececa..fc481760895f824dd810f5d8639557393626dae1 100644 GIT binary patch literal 57344 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 VFqlL6t%P&#hJHVkd4#zS{67HK>GuEt delta 49 zcmV-10M7q_zypB50+1U85C8xG3Xvc`0T8iZpbxU30}!(VAOR2t0T1>75B9SW5bO`L H_CE?>RO=3p diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 30047df..e2ec3c0 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -3,15 +3,17 @@ dotenv.config(); import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; import { loadMapping } from "./lib/impl/mappings"; -import { Format, Type } from "./types/enums"; +import { Type } from "./types/enums"; import { init } from "./database"; import emitter, { Events } from "./lib"; import { get } from "./database/impl/get"; import queues from "./worker"; -import { search } from "./database/impl/search"; +import { deleteEntry } from "./database/impl/delete"; before().then(async (_) => { - await search("Seven", Type.ANIME, [Format.TV], 1, 10).then(console.log); + if (await get("147103")) await deleteEntry("147103"); + + await loadMapping({ id: "147103", type: Type.ANIME }).then(console.log); }); async function before() { diff --git a/anify-backend-recode/src/mappings/impl/information/anilist.ts b/anify-backend-recode/src/mappings/impl/information/anilist.ts index 59f4b7b..9b6e249 100644 --- a/anify-backend-recode/src/mappings/impl/information/anilist.ts +++ b/anify-backend-recode/src/mappings/impl/information/anilist.ts @@ -307,14 +307,17 @@ export default class AniList extends InformationProvider char.name === character.name); + if (!existingCharacter) { + characters.push({ + voiceActor: { + name: character.voiceActors[0]?.name?.full ?? null, + image: character.voiceActors[0]?.image?.large ?? null, + }, + image: character.node.image.large, + name: character.node.name.full, + }); + } } for (const relation of data.relations.edges) { diff --git a/anify-backend-recode/src/mappings/impl/information/mal.ts b/anify-backend-recode/src/mappings/impl/information/mal.ts index e1493ea..62277c4 100644 --- a/anify-backend-recode/src/mappings/impl/information/mal.ts +++ b/anify-backend-recode/src/mappings/impl/information/mal.ts @@ -6,6 +6,8 @@ export default class MAL extends InformationProvider { + override id = "tvdb"; + override url = "https://thetvdb.com"; + + private tvdbApiUrl = "https://api4.thetvdb.com/v4"; + + private apiKeys = ["f5744a13-9203-4d02-b951-fbd7352c1657", "8f406bec-6ddb-45e7-8f4b-e1861e10f1bb", "5476e702-85aa-45fd-a8da-e74df3840baf", "51020266-18f7-4382-81fc-75a4014fa59f"]; + + override get priorityArea(): MediaInfoKeys[] { + return ["bannerImage", "coverImage"]; + } + + override get sharedArea(): MediaInfoKeys[] { + return ["synonyms", "genres", "tags", "artwork", "characters"]; + } + + override async info(media: Anime | Manga): Promise { + const tvdbId = media.mappings.find((data) => { + return data.providerId === "tvdb"; + })?.id; + + if (!tvdbId) return undefined; + + const token = await this.getToken(this.apiKeys[Math.floor(Math.random() * this.apiKeys.length)]); + + const data: Response | undefined = await this.request( + `${this.tvdbApiUrl}${tvdbId}/extended`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + }, + false, + ).catch(() => { + return undefined; + }); + + if (!data) return undefined; + + if (data.ok) { + const info = (await data.json()).data; + + const img = info.image; + const aliases = info.aliases; + const firstAired = new Date(info.firstAired); + + const averageRunTime = info.averageRuntime; + + const characters: Character[] = (info.characters ?? []) + .map((character: any) => { + // Check if the character already exists in the media + const existingCharacter = media.characters.find((char) => char.name === character.name); + if (!existingCharacter) { + return { + name: character.name, + image: character.image, + voiceActor: { + name: character.peopleName ?? character.personName, + image: character.peopleImageURL ?? character.personImgURL, + }, + }; + } + }) + .filter(Boolean); + + const artwork: Artwork[] = info.artworks; + + const artworkIds = { + banner: [1, 16, 6], + poster: [2, 7, 14, 27], + backgrounds: [3, 8, 15], + icon: [5, 10, 18, 19, 26], + clearArt: [22, 24], + clearLogo: [23, 25], + fanart: [11, 12], + actorPhoto: [13], + cinemagraphs: [20, 21], + }; + + const coverImages = artwork.filter((art) => artworkIds.poster.includes(Number(art.type))); + coverImages.sort((a, b) => b.score - a.score); + + const banners = artwork.filter((art) => artworkIds.backgrounds.includes(Number(art.type))); + banners.sort((a, b) => b.score - a.score); + + const genres = info.genres; + + const trailers = info.trailers; + + const airsDays = info.airsDays; // Helpful + + const artworkData = artwork + .map((art) => { + const type = artworkIds.backgrounds.includes(art.type) ? "banner" : artworkIds.banner.includes(art.type) ? "top_banner" : artworkIds.clearLogo.includes(art.type) ? "clear_logo" : artworkIds.poster.includes(art.type) ? "poster" : artworkIds.icon.includes(art.type) ? "icon" : artworkIds.clearArt.includes(art.type) ? "clear_art" : null; + if (!type) return; + return { + type: type, + img: art.image, + providerId: this.id, + }; + }) + .filter(Boolean); + + const hasPrequelRelation = media.relations.some((relation) => relation.relationType === "PREQUEL"); + + const coverImage = !hasPrequelRelation ? coverImages[0]?.image ?? media.coverImage ?? null : media.coverImage ?? null; + + return { + id: media.id, + title: { + english: null, + romaji: null, + native: null, + }, + currentEpisode: null, + trailer: trailers[0]?.url ?? null, + duration: averageRunTime ?? null, + color: null, + bannerImage: banners[0]?.image ?? null, + coverImage, + status: null, + format: Format.UNKNOWN, + season: Season.UNKNOWN, + synonyms: aliases?.map((alias: { name: string }) => alias.name) ?? [], + description: null, + year: Number(info.year ?? firstAired.getFullYear()) ?? null, + totalEpisodes: 0, + genres: genres ? genres.map((genre: { name: string }) => genre.name) : [], + rating: null, + popularity: null, + countryOfOrigin: null, + tags: info.tags?.map((tag: { name: string }) => tag.name) ?? [], + relations: [], + artwork: artworkData as any, + characters: characters.slice(0, 10), + totalChapters: null, + totalVolumes: null, + type: media.type, + }; + } + + return undefined; + } + + private async getToken(key: string): Promise { + const data: Response | undefined = await this.request( + `${this.tvdbApiUrl}/login`, + { + body: JSON.stringify({ + apikey: `${key}`, + }), + method: "POST", + headers: { + "Content-Type": "application/json", + }, + }, + false, + ).catch((err) => { + console.error(err); + return undefined; + }); + if (!data) return undefined; + + if (data.ok) { + return (await data.json()).data.token as string; + } + + return undefined; + } +} + +interface Artwork { + id: number; + image: string; + thumbnail: string; + language: null | string; + type: number; + score: number; + width: number; + height: number; + includesText: boolean; + thumbnailWidth: number; + thumbnailHeight: number; + updatedAt: number; + status: { + id: number; + name: null | string; + }; + tagOptions: null; +} diff --git a/anify-backend-recode/src/mappings/impl/meta/kitsu.ts b/anify-backend-recode/src/mappings/impl/meta/kitsu.ts new file mode 100644 index 0000000..a6af750 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/meta/kitsu.ts @@ -0,0 +1,277 @@ +import MetaProvider from "."; +import { Format, Formats } from "../../../types/enums"; +import { Result } from "../../../types/types"; + +export default class KitsuMeta extends MetaProvider { + override rateLimit = 250; + override id = "kitsu"; + override url = "https://kitsu.io"; + override formats: Format[] = [Format.TV, Format.MOVIE, Format.ONA, Format.SPECIAL, Format.TV_SHORT, Format.OVA, Format.MANGA, Format.ONE_SHOT, Format.NOVEL]; + + private kitsuApiUrl = "https://kitsu.io/api/edge"; + + override async search(query: string, format?: Format, year?: number): Promise { + const results: Result[] = []; + + try { + const data = await ( + await this.request( + `${this.kitsuApiUrl}/anime?filter[text]=${encodeURIComponent(query)}`, + { + headers: { + Accept: "application/vnd.api+json", + "Content-Type": "application/vnd.api+json", + }, + }, + true, + ) + ).json(); + + if (data.data.length > 0) { + data.data.forEach((result: KitsuResult) => { + const altTitles = [result.attributes.titles.en_jp, result.attributes.titles.ja_jp, result.attributes.titles.en_us, result.attributes.titles.en, result.attributes.titles.en_kr, result.attributes.titles.ko_kr, result.attributes.titles.en_cn, result.attributes.titles.zh_cn].filter(Boolean); + + const formatString = result.attributes.subtype.toUpperCase(); + const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + results.push({ + title: result.attributes.titles.en_us || result.attributes.titles.en_jp || result.attributes.titles.ja_jp || result.attributes.titles.en || result.attributes.titles.en_kr || result.attributes.titles.ko_kr || result.attributes.titles.en_cn || result.attributes.titles.zh_cn || result.attributes.canonicalTitle || result.attributes.slug, + altTitles: altTitles, + id: result.id, + img: result.attributes.posterImage?.original ?? null, + format, + year: result.attributes.startDate ? new Date(result.attributes.startDate).getFullYear() : 0, + providerId: this.id, + }); + }); + } + } catch (e) { + // + } + + try { + const data = await ( + await this.request( + `${this.kitsuApiUrl}/manga?filter[text]=${encodeURIComponent(query)}`, + { + headers: { + Accept: "application/vnd.api+json", + "Content-Type": "application/vnd.api+json", + }, + }, + true, + ) + ).json(); + + if (data.data.length > 0) { + data.data.forEach((result: KitsuResult) => { + const altTitles = [result.attributes.titles.en_jp, result.attributes.titles.ja_jp, result.attributes.titles.en_us, result.attributes.titles.en, result.attributes.titles.en_kr, result.attributes.titles.ko_kr, result.attributes.titles.en_cn, result.attributes.titles.zh_cn].filter(Boolean); + + const formatString = result.attributes.subtype.toUpperCase(); + const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + results.push({ + title: result.attributes.titles.en_us || result.attributes.titles.en_jp || result.attributes.titles.ja_jp || result.attributes.titles.en || result.attributes.titles.en_kr || result.attributes.titles.ko_kr || result.attributes.titles.en_cn || result.attributes.titles.zh_cn || result.attributes.canonicalTitle || result.attributes.slug, + altTitles: altTitles, + id: result.id, + img: result.attributes.posterImage?.original ?? null, + format, + year: result.attributes.startDate ? new Date(result.attributes.startDate).getFullYear() : 0, + providerId: this.id, + }); + }); + } + } catch (e) { + // + } + + return results; + } +} + +type KitsuResult = { + id: string; + type: string; + links: { + self: string; + }; + attributes: { + createdAt: string; + updatedAt: string; + slug: string; + synopsis: string; + description: string; + coverImageTopOffset: number; + titles: { + en: string; + en_us: string; + en_kr: string; + en_cn: string; + en_jp: string; + fr_fr: string; + ja_jp: string; + ko_kr: string; + pt_pt: string; + ru_ru: string; + th_th: string; + zh_cn: string; + }; + canonicalTitle: string; + abbreviatedTitles: string[]; + averageRating: string; + ratingFrequencies: { + [key: string]: string; + }; + userCount: number; + favoritesCount: number; + startDate: string; + endDate: string | null; + nextRelease: string | null; + popularityRank: number; + ratingRank: number; + ageRating: string; + ageRatingGuide: string | null; + subtype: string; + status: string; + tba: string | null; + posterImage: { + tiny: string; + large: string; + small: string; + medium: string; + original: string; + meta: { + dimensions: { + tiny: { + width: number; + height: number; + }; + large: { + width: number; + height: number; + }; + small: { + width: number; + height: number; + }; + medium: { + width: number; + height: number; + }; + }; + }; + }; + coverImage: { + tiny: string; + large: string; + small: string; + original: string; + meta: { + dimensions: { + tiny: { + width: number; + height: number; + }; + large: { + width: number; + height: number; + }; + small: { + width: number; + height: number; + }; + }; + }; + }; + chapterCount: number | null; + volumeCount: number | null; + serialization: string; + mangaType: string; + }; + relationships: { + genres: { + links: { + self: string; + related: string; + }; + }; + categories: { + links: { + self: string; + related: string; + }; + }; + castings: { + links: { + self: string; + related: string; + }; + }; + installments: { + links: { + self: string; + related: string; + }; + }; + mappings: { + links: { + self: string; + related: string; + }; + }; + reviews: { + links: { + self: string; + related: string; + }; + }; + mediaRelationships: { + links: { + self: string; + related: string; + }; + }; + characters: { + links: { + self: string; + related: string; + }; + }; + staff: { + links: { + self: string; + related: string; + }; + }; + productions: { + links: { + self: string; + related: string; + }; + }; + quotes: { + links: { + self: string; + related: string; + }; + }; + chapters: { + links: { + self: string; + related: string; + }; + }; + mangaCharacters: { + links: { + self: string; + related: string; + }; + }; + mangaStaff: { + links: { + self: string; + related: string; + }; + }; + }; +}; diff --git a/anify-backend-recode/src/mappings/impl/meta/mal.ts b/anify-backend-recode/src/mappings/impl/meta/mal.ts index e69de29..783e9e5 100644 --- a/anify-backend-recode/src/mappings/impl/meta/mal.ts +++ b/anify-backend-recode/src/mappings/impl/meta/mal.ts @@ -0,0 +1,94 @@ +import MetaProvider from "."; +import { Format } from "../../../types/enums"; +import { Result } from "../../../types/types"; + +export default class MALMeta extends MetaProvider { + override id = "mal"; + override url = "https://myanimelist.net"; + + private api = "https://api.jikan.moe/v4"; + + override rateLimit = 500; + override formats: Format[] = [Format.TV, Format.MOVIE, Format.ONA, Format.SPECIAL, Format.TV_SHORT, Format.OVA, Format.MANGA, Format.ONE_SHOT, Format.NOVEL]; + + override async search(query: string, format?: Format | undefined, year?: number | undefined): Promise { + const results: Result[] = []; + + const anime = await (await this.request(`${this.api}/anime?q=${encodeURIComponent(query)}&sfw`, {}, true)).json(); + const manga = await (await this.request(`${this.api}/manga?q=${encodeURIComponent(query)}&sfw`, {}, true)).json(); + + for (const data of anime.data) { + results.push({ + id: String(data.mal_id), + altTitles: data.title_synonyms?.filter((s: string) => s?.length) ?? [], + format: data.type?.toLowerCase() === "tv" ? Format.TV : data.type?.toLowerCase() === "movie" ? Format.MOVIE : data.type?.toLowerCase() === "ova" ? Format.OVA : data.type?.toLowerCase() === "special" ? Format.SPECIAL : data.type?.toLowerCase() === "ona" ? Format.ONA : data.type?.toLowerCase() === "music" ? Format.MUSIC : data.type?.toLowerCase() === "manga" ? Format.MANGA : data.type?.toLowerCase() === "novel" ? Format.NOVEL : data.type?.toLowerCase() === "lightnovel" ? Format.NOVEL : data.type?.toLowerCase() === "oneshot" ? Format.ONE_SHOT : data.type?.toLowerCase() === "doujin" ? Format.MANGA : data.type?.toLowerCase() === "manhwa" ? Format.MANGA : data.type?.toLowerCase() === "manhua" ? Format.MANGA : Format.UNKNOWN, + img: data.images?.jpg?.large_image_url ?? data.images?.jpg?.image_url ?? data.images?.jpg?.small_image_url ?? null, + providerId: this.id, + title: data.title ?? data.title_english ?? data.title_japanese ?? "", + year: data.year ? data.year : data.published ? (data.published.from ? new Date(data.published).getFullYear() : data.published.prop ? data.published.prop.from?.year : null) : null, + }); + } + + for (const data of manga.data) { + results.push({ + id: String(data.mal_id), + altTitles: data.title_synonyms?.filter((s: string) => s?.length) ?? [], + format: data.type?.toLowerCase() === "tv" ? Format.TV : data.type?.toLowerCase() === "movie" ? Format.MOVIE : data.type?.toLowerCase() === "ova" ? Format.OVA : data.type?.toLowerCase() === "special" ? Format.SPECIAL : data.type?.toLowerCase() === "ona" ? Format.ONA : data.type?.toLowerCase() === "music" ? Format.MUSIC : data.type?.toLowerCase() === "manga" ? Format.MANGA : data.type?.toLowerCase() === "novel" ? Format.NOVEL : data.type?.toLowerCase() === "lightnovel" ? Format.NOVEL : data.type?.toLowerCase() === "oneshot" ? Format.ONE_SHOT : data.type?.toLowerCase() === "doujin" ? Format.MANGA : data.type?.toLowerCase() === "manhwa" ? Format.MANGA : data.type?.toLowerCase() === "manhua" ? Format.MANGA : Format.UNKNOWN, + img: data.images?.jpg?.large_image_url ?? data.images?.jpg?.image_url ?? data.images?.jpg?.small_image_url ?? null, + providerId: this.id, + title: data.title ?? data.title_english ?? data.title_japanese ?? "", + year: data.year ? data.year : data.published ? (data.published.from ? new Date(data.published).getFullYear() : data.published.prop ? data.published.prop.from?.year : null) : null, + }); + } + + return results; + } +} + +type JikanResponse = { + mal_id: number; + url: string; + title: string; + title_english: string | null; + title_japanese: string | null; + title_synonyms: string[]; + type: string; + status: string; + synopsis: string | null; + images: { + jpg: { + image_url: string | null; + small_image_url: string | null; + large_image_url: string | null; + }; + webp: { + image_url: string | null; + small_image_url: string | null; + large_image_url: string | null; + }; + }; + duration: string; + episodes: number | null; + popularity: number | null; + score: number | null; + season: string; + year: number | null; + genres: { name: string }[]; + trailer: { + youtube_id: string | null; + url: string | null; + embed_url: string | null; + images: { + image_url: string | null; + small_image_url: string | null; + medium_image_url: string | null; + large_image_url: string | null; + maximum_image_url: string | null; + }; + }; + approved: boolean; + titles: { + type: string; + title: string; + }[]; +}; diff --git a/anify-backend-recode/src/mappings/impl/meta/tmdb.ts b/anify-backend-recode/src/mappings/impl/meta/tmdb.ts new file mode 100644 index 0000000..e336fa6 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/meta/tmdb.ts @@ -0,0 +1,115 @@ +import MetaProvider from "."; +import { Format } from "../../../types/enums"; +import { Result } from "../../../types/types"; + +export default class TMDB extends MetaProvider { + override rateLimit = 500; + override id = "tmdb"; + override url = "https://themoviedb.org"; + override formats: Format[] = [Format.TV, Format.MOVIE, Format.ONA, Format.SPECIAL, Format.TV_SHORT, Format.OVA]; + + private tmdbApiUrl = "https://api.themoviedb.org/3"; + private apiKey = "5201b54eb0968700e693a30576d7d4dc"; + + override async search(query: string, format?: Format, year?: number): Promise { + const results: Result[] = []; + + const page = 1; + const searchUrl = `/search/multi?api_key=${this.apiKey}&language=en-US&page=${page}&include_adult=false&query=${encodeURIComponent(query)}`; + + const data = await (await this.request(this.tmdbApiUrl + searchUrl)).json(); + + if (!data) return undefined; + + if (data.results.length > 0) { + data.results.forEach((result: TMDBResult) => { + if (result.media_type === "tv") { + results.push({ + id: `/tv/${result.id}`, + title: result.title || result.name, + altTitles: [result.original_title || result.original_name, result.title || result.name], + img: `https://image.tmdb.org/t/p/w500${result.poster_path}`, + format: Format.UNKNOWN, + year: result.first_air_date ? new Date(result.first_air_date).getFullYear() : 0, + providerId: this.id, + }); + } else if (result.media_type === "movie") { + results.push({ + id: `/movie/${result.id}`, + title: result.title || result.name, + altTitles: [result.original_title || result.original_name, result.title || result.name], + img: `https://image.tmdb.org/t/p/w500${result.poster_path}`, + format: Format.MOVIE, + year: result.first_air_date ? new Date(result.first_air_date).getFullYear() : 0, + providerId: this.id, + }); + } + }); + return results; + } else { + return results; + } + } +} + +type TMDBResult = { + adult: boolean; + backdrop_path: string | null; + id: number; + title?: string; + name: string; + original_language: string; + original_title?: string; + original_name: string; + overview: string; + poster_path: string | null; + media_type: string; + genre_ids: number[]; + popularity: number; + first_air_date: string; + vote_average: number; + vote_count: number; + origin_country: string[]; +}; + +type Episode = { + air_date: string; + episode_number: number; + episode_type: string; + id: number; + name: string; + overview: string; + production_code: string; + runtime: number; + season_number: number; + show_id: number; + still_path: string; + vote_average: number; + vote_count: number; + crew: { + job: string; + department: string; + credit_id: string; + adult: boolean; + gender: number; + id: number; + known_for_department: string; + name: string; + original_name: string; + popularity: number; + profile_path: string | null; + }[]; + guest_stars: { + character: string; + credit_id: string; + order: number; + adult: boolean; + gender: number; + id: number; + known_for_department: string; + name: string; + original_name: string; + popularity: number; + profile_path: string | null; + }[]; +}; diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend-recode/src/mappings/index.ts index fa32000..bf38ccb 100644 --- a/anify-backend-recode/src/mappings/index.ts +++ b/anify-backend-recode/src/mappings/index.ts @@ -9,9 +9,14 @@ import AniListBase from "./impl/base/anilist"; import InformationProvider from "./impl/information"; import AniList from "./impl/information/anilist"; import Kitsu from "./impl/information/kitsu"; +import MAL from "./impl/information/mal"; +import TVDB from "./impl/information/tvdb"; import MangaProvider from "./impl/manga"; import MetaProvider from "./impl/meta"; import AniListMeta from "./impl/meta/anilist"; +import KitsuMeta from "./impl/meta/kitsu"; +import MALMeta from "./impl/meta/mal"; +import TMDB from "./impl/meta/tmdb"; import TheTVDB from "./impl/meta/tvdb"; const ANIME_PROVIDERS: AnimeProvider[] = [new NineAnime(), new AnimePahe(), new GogoAnime(), new Zoro()]; @@ -32,7 +37,7 @@ const mangaProviders: Record = MANGA_PROVIDERS.reduce( {} as Record, ); -const INFORMATION_PROVIDERS: InformationProvider[] = [new AniList(), new Kitsu()]; +const INFORMATION_PROVIDERS: InformationProvider[] = [new AniList(), new Kitsu(), new MAL(), new TVDB()]; const infoProviders: Record> = INFORMATION_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; @@ -41,7 +46,7 @@ const infoProviders: Record>, ); -const META_PROVIDERS: MetaProvider[] = [new TheTVDB(), new AniListMeta()]; +const META_PROVIDERS: MetaProvider[] = [new TheTVDB(), new AniListMeta(), new MALMeta(), new KitsuMeta(), new TMDB()]; const metaProviders: Record = META_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; From 6c041d4cb0c7fe6f4f0584563e3c2d924d4fbc7f Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 6 Sep 2023 14:15:33 -0400 Subject: [PATCH 10/77] Add manga providers --- anify-backend-recode/db.sqlite | Bin 57344 -> 61440 bytes anify-backend-recode/src/database/impl/get.ts | 1 + anify-backend-recode/src/helper/index.ts | 6 + anify-backend-recode/src/helper/title.ts | 16 ++ anify-backend-recode/src/index.ts | 6 +- anify-backend-recode/src/lib/impl/mappings.ts | 2 +- .../src/mappings/impl/information/comick.ts | 154 +++++++++++++++ .../src/mappings/impl/information/mangadex.ts | 72 +++++++ .../src/mappings/impl/manga/comick.ts | 185 ++++++++++++++++++ .../src/mappings/impl/manga/jnovels.ts | 95 +++++++++ .../src/mappings/impl/manga/mangadex.ts | 165 ++++++++++++++++ .../src/mappings/impl/manga/mangasee.ts | 128 ++++++++++++ .../src/mappings/impl/meta/mal.ts | 106 +++------- anify-backend-recode/src/mappings/index.ts | 10 +- 14 files changed, 866 insertions(+), 80 deletions(-) create mode 100644 anify-backend-recode/src/mappings/impl/information/comick.ts create mode 100644 anify-backend-recode/src/mappings/impl/information/mangadex.ts create mode 100644 anify-backend-recode/src/mappings/impl/manga/comick.ts create mode 100644 anify-backend-recode/src/mappings/impl/manga/jnovels.ts create mode 100644 anify-backend-recode/src/mappings/impl/manga/mangadex.ts create mode 100644 anify-backend-recode/src/mappings/impl/manga/mangasee.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index fc481760895f824dd810f5d8639557393626dae1..27950dbc4d13e538cfedd1639cec5dbb2e712de1 100644 GIT binary patch delta 6075 zcmcgwTWlQF8MYG=a7r;zDKvF~lMN6m`RwkTxf?5Gyn7rL;w@#2Zposq~-OHQ2N^ z`w%Qy>p8dYeE;>F^PhQp`U#@+4v_uM}{j~|@xdOm;lvE9$Jwytf@jNW(O z_fFk$$NcseXXp9bw_R`l$zF~poI*6a!m#Gf6@sAb_oPxK<|cKwWa-6Z+0uiG$NW@L zam%yMB~O&|;mPht!cQLBSu0T|Pg5Fo9Ok7ONO)p2>lX$Nn`%ileaCu0Ns7S0`<9b(CN^?nqkm)^X$c&XJ5TJ|Ju!S zFWo%5lsNs=sf1;~0ClnAxVQiy{KSv|Ys#KGV;RgFj)oiT*YqB#mLt6J%)!A-_|AKK zrkEibhM}jis;UMSOoL!5rwLX~W^zm?x+;om*2k!^zy^yLuI{!Dm-}N^Z>*C@6xe3LK4TjJ0I{77MTQsN`&!ubzHpmLgmn1U>-UCN-hZU_^izosfBK`p|6uVi*Uta# zwFQ8wFVEMPFW0ZVSYQ5ieffp@^3Utb3vuT!;*X260W?ta{b1+ zm4%fnH(o+FUR?PNe4K@j>(N()e(9C^k-I|me5K5`ut6d2Ons=ps;)F@d_5cM%yLNq{r+4TY+mEBq972Jx? zP|hkb3yoA9%k>a-3^c{!&mk*cNTQ({+wUXGLAE=?(5w{{0MswCK%=&e$~LVs4`mA$ zc#mH}qttP`WXo2#Y-_0oMQIfKJ8YT{{&Lm=5CEcr0)+2~%>2w@g@y}|Ea)j^# z0Z%bq4_pGmZ{lF?nW>?PBjJU;B>Zur^WilLGf~jczMC{+qwbOu=2X`N*wRoc@`>b8j;>lUJKs76f9T?V*&@zp7UdOM2 zS`MrdFtGH`@tL${sO`m?VNRJ^c+{;Fs1^CqMoA+qB0Gr0~-4rV01r1%qv&I-T&;Z1IoD5>-kWB_G&kxWPWQs^>kTLWEY6#zG zuC`Eb8z-g?zTm+jYgm<1N}Fq*oQIFj76x;DPdq924~7d@_lJL2 zdTjsN1vd5aY{U5n!qU};P-FhaM=}79?_C4>j8&p}INinQm`S;w1<8uq;q}*h!;h|Z zCK@x#t`FjDFm>VTJ>k2r@2Xj)JOp@aHwe&SGa?(%&|Y^;HuKKuZaD0}5S9$Gv5{mA z?i#lgws?GO+Kp~7t)bQ+&9uUHvO0RWuXWfKQRzg@vGcbacA7iEyw*@_(QUCsw)v6c zgGy_#Eu%i`r>13XX8abz`l*qlPCmMSFCMz>@ty6RAGdXWytMo7e|GNb*uJNu5xR?4 z{Ypd6k{}Z6mWgYJGN!QD#;;ihaT6q_wI8mWG zr~=S!c$A7CXWSCgQpgiR4mGz%$uf6 zd7XV}ZSlzll3iQqccS@6;8ptZpsjGX^N@J3z(Bwhrw%{Axk3J zGB$!ND4HgKrDT-@ONnVr1x3Wflsh!d;1pitjGR$bHGQ{G59d(N8}*gq=6C>SO=5RvdBZ~jtupUjn0V> z{qCE)or-OD!*v~=6N#Rv5!Qd-m*iBA2m}w!OiTyT966TDWSZxqLrYOXZe7hNyzuCr z&44&OK>KsYCdasJe#C2@7EPdab)QXupx!A7GA3Gq3{A+YK-kIkj7FgV17!uDLP3Xa z4AdP1DR}JobNxeObCdk=aj2HYSEnYUA$UqbISSt6?#3{f5RvB~W#p`bM{~N)&1I{f z;{z4as9Ne(E0v9L9wv%HI3A~G^?d*AgjW>?RNG`ixs7w{ikH+D_S>1$GD#np; z#nX%O(abE(@#1=%sB{9g#v!m76ofWbPlJ(+2S-m1l=`#jCx!77>ye^DlJiB3GLIO{ Vq!l|@zjnG(w2JO(WH_5ueuHa0jnHZ-E64YI%m5VHla`VRpNg8Uos diff --git a/anify-backend-recode/src/database/impl/get.ts b/anify-backend-recode/src/database/impl/get.ts index ec4f72b..87c83ce 100644 --- a/anify-backend-recode/src/database/impl/get.ts +++ b/anify-backend-recode/src/database/impl/get.ts @@ -30,6 +30,7 @@ export const get = async (id: string): Promise => { try { Object.assign(anime, { title: JSON.parse((anime as any).title), + season: (anime as any).season.replace(/"/g, ""), mappings: JSON.parse((anime as any).mappings), synonyms: JSON.parse((anime as any).synonyms), rating: JSON.parse((anime as any).rating), diff --git a/anify-backend-recode/src/helper/index.ts b/anify-backend-recode/src/helper/index.ts index 68e61c7..cbdf84d 100644 --- a/anify-backend-recode/src/helper/index.ts +++ b/anify-backend-recode/src/helper/index.ts @@ -1,3 +1,9 @@ +export function wait(time: number) { + return new Promise((resolve) => { + setTimeout(resolve, time); + }); +} + export function substringBefore(str: string, toFind: string) { const index = str.indexOf(toFind); return index == -1 ? "" : str.substring(0, index); diff --git a/anify-backend-recode/src/helper/title.ts b/anify-backend-recode/src/helper/title.ts index c5f69a9..33b6dcd 100644 --- a/anify-backend-recode/src/helper/title.ts +++ b/anify-backend-recode/src/helper/title.ts @@ -103,3 +103,19 @@ export const slugify = (...args: (string | number)[]): string => { .replace(/[^a-z0-9 ]/g, "-") .replace(/\s+/g, "-"); }; + +export function stringSearch(string: string, pattern: string): number { + let count = 0; + string = string.toLowerCase(); + pattern = pattern.toLowerCase(); + string = string.replace(/[^a-zA-Z0-9 -]/g, ""); + pattern = pattern.replace(/[^a-zA-Z0-9 -]/g, ""); + + for (let i = 0; i < string.length; i++) { + for (let j = 0; j < pattern.length; j++) { + if (pattern[j] !== string[i + j]) break; + if (j === pattern.length - 1) count++; + } + } + return count; +} diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index e2ec3c0..011e9df 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -9,11 +9,13 @@ import emitter, { Events } from "./lib"; import { get } from "./database/impl/get"; import queues from "./worker"; import { deleteEntry } from "./database/impl/delete"; +import { mangaProviders } from "./mappings"; before().then(async (_) => { - if (await get("147103")) await deleteEntry("147103"); + if (await get("132182")) await deleteEntry("132182"); + await loadMapping({ id: "132182", type: Type.MANGA }).then(console.log); - await loadMapping({ id: "147103", type: Type.ANIME }).then(console.log); + //mangaProviders.mangasee.fetchPages("/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-chapter-1").then(console.log); }); async function before() { diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend-recode/src/lib/impl/mappings.ts index 8e18ddf..33284b5 100644 --- a/anify-backend-recode/src/lib/impl/mappings.ts +++ b/anify-backend-recode/src/lib/impl/mappings.ts @@ -170,7 +170,7 @@ export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | Ma const providerTitles = providerData.map((m: Result) => { const titles = [m.title, ...(m.altTitles ?? [])]; - return titles; + return titles.filter(isString); }); // If there are no results, skip diff --git a/anify-backend-recode/src/mappings/impl/information/comick.ts b/anify-backend-recode/src/mappings/impl/information/comick.ts new file mode 100644 index 0000000..07e9e29 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/information/comick.ts @@ -0,0 +1,154 @@ +import InformationProvider from "."; +import { Format, Genres, MediaStatus, Season } from "../../../types/enums"; +import { Anime, AnimeInfo, Manga, MangaInfo, MediaInfoKeys } from "../../../types/types"; + +export default class ComicKInfo extends InformationProvider { + override id = "comick"; + override url = "https://comick.app"; + + private api = "https://api.comick.fun"; + + override get priorityArea(): MediaInfoKeys[] { + return ["coverImage", "description"]; + } + + override get sharedArea(): MediaInfoKeys[] { + return ["synonyms", "genres", "artwork", "tags"]; + } + + override async info(media: Anime | Manga): Promise { + const comicKId = media.mappings.find((data) => { + return data.providerId === "comick"; + })?.id; + + if (!comicKId) return undefined; + + const req = await this.request(`${this.api}/comic/${comicKId}`, {}, true); + + if (!req.ok) return undefined; + + const coverReq = await this.request(`${this.api}/comic/${comicKId}/covers`, {}, true); + const covers: Covers = await coverReq.json(); + + const data: Comic = (await req.json()).comic; + + return { + id: String(data.slug), + type: media.type, + artwork: covers.md_covers.map((cover) => { + return { + img: "https://meo.comick.pictures/" + cover.b2key, + type: "poster", + providerId: this.id, + }; + }), + bannerImage: null, + characters: [], + color: null, + countryOfOrigin: data.country, + coverImage: + covers.md_covers.map((cover) => { + if (cover.is_primary) { + return `https://meo.comick.pictures/${cover.b2key}`; + } + })[0] ?? + data.md_covers.map((cover) => `https://meo.comick.pictures/${cover.b2key}`)[0] ?? + null, + currentEpisode: null, + description: data.parsed, + duration: null, + format: Format.UNKNOWN, + genres: + (data.md_comic_md_genres.map((genre) => { + return genre.md_genres.name; + }) as Genres[]) ?? [], + popularity: Number(data.user_follow_count), + rating: Number(data.bayesian_rating), + relations: [], + season: Season.UNKNOWN, + status: data.status === 1 ? MediaStatus.FINISHED : MediaStatus.RELEASING, + synonyms: data.md_titles.map((title) => title.title), + tags: data.mu_comics.mu_comic_categories.map((genre) => { + return genre.mu_categories.title; + }), + title: { + english: data.md_titles.find((title) => title.lang === "en")?.title ?? data.title, + native: data.md_titles.find((title) => title.lang === "ja")?.title ?? null, + romaji: data.md_titles.find((title) => title.lang === "ja-ro")?.title ?? null, + }, + totalChapters: null, + totalVolumes: null, + trailer: null, + year: data.year, + }; + } +} + +interface Comic { + id: number; + hid: string; + title: string; + country: string; + status: number; + links: { al: string; ap: string; bw: string; kt: string; mu: string; amz: string; cdj: string; ebj: string; mal: string; raw: string }; + last_chapter: any; + chapter_count: number; + demographic: number; + hentai: boolean; + user_follow_count: number; + follow_rank: number; + comment_count: number; + follow_count: number; + desc: string; + parsed: string; + slug: string; + mismatch: any; + year: number; + bayesian_rating: any; + rating_count: number; + content_rating: string; + translation_completed: boolean; + relate_from: Array; + mies: any; + md_titles: { title: string; lang?: string }[]; + md_comic_md_genres: { md_genres: { name: string; type: string | null; slug: string; group: string } }[]; + mu_comics: { + licensed_in_english: any; + mu_comic_categories: { + mu_categories: { title: string; slug: string }; + positive_vote: number; + negative_vote: number; + }[]; + }; + md_covers: { vol: any; w: number; h: number; b2key: string }[]; + iso639_1: string; + lang_name: string; + lang_native: string; +} + +interface Covers { + id: number; + title: string; + slug: string; + links2: { + id: string; + slug: string; + enable: boolean; + }[]; + noindex: boolean; + country: string; + md_covers: { + id: number; + w: number; + h: number; + s: number; + gpurl: string; + md_comic_id: number; + url: string; + vol: string; + mdid: string | null; + b2key: string; + is_primary: boolean; + locale: string | boolean; + }[]; +} diff --git a/anify-backend-recode/src/mappings/impl/information/mangadex.ts b/anify-backend-recode/src/mappings/impl/information/mangadex.ts new file mode 100644 index 0000000..da38592 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/information/mangadex.ts @@ -0,0 +1,72 @@ +import InformationProvider from "."; +import { Format, MediaStatus, Season } from "../../../types/enums"; +import { Anime, AnimeInfo, Manga, MangaInfo, MediaInfoKeys } from "../../../types/types"; + +export default class MangaDexInfo extends InformationProvider { + override id = "mangadex"; + override url = "https://mangadex.org"; + + private api = "https://api.mangadex.org"; + + override get priorityArea(): MediaInfoKeys[] { + return []; + } + + override get sharedArea(): MediaInfoKeys[] { + return ["synonyms", "genres", "artwork", "tags"]; + } + + override async info(media: Anime | Manga): Promise { + const mangadexId = media.mappings.find((data) => { + return data.providerId === "mangadex"; + })?.id; + + if (!mangadexId) return undefined; + + const data = (await (await this.request(`${this.api}/manga/${mangadexId}`, {}, true)).json()).data; + const covers = await (await this.request(`${this.api}/cover?limit=100&manga[]=${mangadexId}`, {}, true)).json(); + + return { + id: mangadexId, + type: media.type, + title: { + romaji: data.attributes.title.jp_ro ?? null, + english: data.attributes.title.en ?? null, + native: data.attributes.title.jp ?? null, + }, + synonyms: data.attributes.altTitles.map((title: { [key: string]: string }) => { + return Object.values(title)[0]; + }), + description: data.attributes.description.en ?? data.attributes.description.jp ?? data.attributes.description.jp_ro ?? data.attributes.description.ko ?? Object.values(data.attributes.description)[0], + countryOfOrigin: data.attributes.publicationDemographic ?? data.attributes.originalLanguage?.toUpperCase() ?? null, + characters: [], + genres: data.attributes.tags.filter((tag: any) => tag.attributes.group === "genre").map((tag: any) => tag.attributes.name.en), + year: data.attributes.year, + artwork: covers.data.map((cover: any) => { + const img = `${this.url}/covers/${mangadexId}/${cover.attributes.fileName}`; + const providerId = this.id; + const type = "poster"; + return { + img, + providerId, + type, + }; + }), + totalChapters: data.attributes.lastChapter ?? null, + totalVolumes: data.attributes.lastVolume ?? null, + status: data.attributes.status === "ongoing" ? MediaStatus.RELEASING : data.attributes.status === "completed" ? MediaStatus.FINISHED : null, + color: null, + currentEpisode: null, + duration: null, + popularity: null, + relations: [], + tags: data.attributes.tags.filter((tag: any) => tag.attributes.group === "theme").map((tag: any) => tag.attributes.name.en), + rating: null, + season: Season.UNKNOWN, + trailer: null, + format: Format.UNKNOWN, + coverImage: `${this.url}/covers/${mangadexId}/${data.relationships.find((element: any) => element.type === "cover_art").id}.jpg`, + bannerImage: null, + }; + } +} diff --git a/anify-backend-recode/src/mappings/impl/manga/comick.ts b/anify-backend-recode/src/mappings/impl/manga/comick.ts new file mode 100644 index 0000000..a38a5a0 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/manga/comick.ts @@ -0,0 +1,185 @@ +import MangaProvider from "."; +import { Format } from "../../../types/enums"; +import { Chapter, Page, Result } from "../../../types/types"; + +export default class ComicK extends MangaProvider { + override rateLimit = 250; + override id = "comick"; + override url = "https://comick.app"; + + override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; + + // Docs: https://upload.comick.app/docs/static/index.html + private api = "https://api.comick.fun"; + + override async search(query: string, format?: Format, year?: number): Promise { + const data: SearchResult[] = await (await this.request(`${this.api}/v1.0/search?q=${encodeURIComponent(query)}&limit=25&page=1${year ? `&from=${year}&to=${year}` : ""}`, {}, true)).json(); + + const results: Result[] = []; + + for (let i = 0; i < data.length; i++) { + const result = data[i]; + + let cover: any = result.md_covers ? result.md_covers[0] : null; + if (cover && cover.b2key != undefined) { + cover = "https://meo.comick.pictures/" + cover.b2key; + } + + results.push({ + id: result.slug, + title: result.title ?? result.slug, + altTitles: result.md_titles ? result.md_titles.map((title) => title.title) : [], + img: cover, + format: format ?? Format.UNKNOWN, + year: result.year ?? 0, + providerId: this.id, + }); + } + + return results; + } + + override async fetchChapters(id: string): Promise { + const chapterList: Chapter[] = []; + + const comicId = await this.getComicId(`/comic/${id}`); + if (!comicId) { + return chapterList; + } + + const data = await (await this.request(`${this.api}/comic/${comicId}/chapters?lang=en&page=0&limit=1000000`, {}, true))?.json(); + + const chapters: Chapter[] = []; + + data.chapters.map((chapter: ComickChapter) => { + let title = ""; + + if (chapter.vol) { + title += "Vol. " + this.padNum(chapter.vol, 2) + " "; + } + if (chapter.chap) { + title += "Ch. " + this.padNum(chapter.chap, 2) + " "; + } + + let canPush = true; + for (let i = 0; i < chapters.length; i++) { + if (chapters[i].title?.trim() === title?.trim()) { + canPush = false; + } + } + + if (canPush) { + const updatedAt = new Date(chapter.updated_at ?? 0).getTime(); + if (chapter.lang === "en") { + chapters.push({ + id: chapter.hid, + title: title?.trim(), + number: Number(chapter.chap), + updatedAt, + }); + } + } + }); + + chapterList.push(...chapters); + + return chapterList; + } + + override async fetchPages(id: string): Promise { + const data = await (await this.request(`${this.api}/chapter/${id}`, {}, true))?.json(); + + const pages: Page[] = []; + + data.chapter.md_images.map((image: { vol: any; w: number; h: number; b2key: string }, index: number) => { + pages.push({ + url: `https://meo.comick.pictures/${image.b2key}?width=${image.w}`, + index: index, + headers: {}, + }); + }); + + return pages; + } + + private async getComicId(id: string): Promise { + const json = await (await this.request(`${this.api}${id}`, {}, true))?.json(); + const data: Comic = json.comic; + return data ? data.hid : null; + } +} + +interface SearchResult { + title: string; + id: number; + slug: string; + year?: number; + rating: string; + rating_count: number; + follow_count: number; + user_follow_count: number; + content_rating: string; + created_at: string; + demographic: number; + md_titles: { title: string }[]; + md_covers: { vol: any; w: number; h: number; b2key: string }[]; + highlight: string; +} + +interface Comic { + id: number; + hid: string; + title: string; + country: string; + status: number; + links: { al: string; ap: string; bw: string; kt: string; mu: string; amz: string; cdj: string; ebj: string; mal: string; raw: string }; + last_chapter: any; + chapter_count: number; + demographic: number; + hentai: boolean; + user_follow_count: number; + follow_rank: number; + comment_count: number; + follow_count: number; + desc: string; + parsed: string; + slug: string; + mismatch: any; + year: number; + bayesian_rating: any; + rating_count: number; + content_rating: string; + translation_completed: boolean; + relate_from: Array; + mies: any; + md_titles: { title: string }[]; + md_comic_md_genres: { md_genres: { name: string; type: string | null; slug: string; group: string } }[]; + mu_comics: { + licensed_in_english: any; + mu_comic_categories: { + mu_categories: { title: string; slug: string }; + positive_vote: number; + negative_vote: number; + }[]; + }; + md_covers: { vol: any; w: number; h: number; b2key: string }[]; + iso639_1: string; + lang_name: string; + lang_native: string; +} + +interface ComickChapter { + id: number; + chap: string; + title: string; + vol: string | null; + lang: string; + created_at: string; + updated_at: string; + up_count: number; + down_count: number; + group_name: any; + hid: string; + identities: any; + md_chapter_groups: { md_groups: { title: string; slug: string } }[]; +} diff --git a/anify-backend-recode/src/mappings/impl/manga/jnovels.ts b/anify-backend-recode/src/mappings/impl/manga/jnovels.ts new file mode 100644 index 0000000..ed6bd6a --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/manga/jnovels.ts @@ -0,0 +1,95 @@ +import { load } from "cheerio"; +import { compareTwoStrings } from "../../../helper/stringSimilarity"; +import MangaProvider from "."; +import { Format } from "../../../types/enums"; +import { Chapter, Page, Result } from "../../../types/types"; + +export default class JNovels extends MangaProvider { + override rateLimit = 250; + override id = "jnovels"; + override url = "https://jnovels.com"; + + override formats: Format[] = [Format.NOVEL]; + + override async search(query: string, format?: Format, year?: number): Promise { + const lightNovels = await (await this.request(`${this.url}/11light-1novel27-pdf/`)).text(); + const novelResults = await this.handleSearchResults(query, lightNovels); + + if (novelResults?.length > 0) return novelResults; + + const webNovels = await (await this.request(`${this.url}/hwebnovels-lista14/`)).text(); + const webResults = await this.handleSearchResults(query, webNovels); + + return webResults; + } + + private async handleSearchResults(query: string, data: string) { + const $ = load(data); + + const elements = $("div.post-content ol li").toArray(); + + const resultsPromises: Promise[] = elements.map(async (el) => { + const item = $(el); + const id = item.find("a").attr("href")?.split(this.url)[1]!; + const title = item.find("a").text()?.trim() ?? ""; + + // If contains style attribute skip + if (item.find("a").attr("style")) return {} as Result; + + if (compareTwoStrings(title, query) < 0.5) return {} as Result; + + const pageData = await (await this.request(`${this.url}${id}`, {}, true)).text(); + const $$ = load(pageData); + + let associated = []; + if ($$("div#editassociated").length === 0) { + const associatedNamesLabel = $$('p:contains("Associated Names")').text()?.split("Related Series")[0]; + associated = associatedNamesLabel + .split("\n") + .slice(1) + .map((x) => x.trim()); + } else { + associated = $$("div#editassociated").text().split("\n"); + } + + return { + id: id, + altTitles: associated?.length > 0 ? associated.map((x) => x.trim()).filter((x) => x.length != 0) : [], + format: Format.NOVEL, + img: $$("div.featured-media img").attr("src") ?? "", + providerId: this.id, + title: title, + year: 0, + }; + }); + + const results = (await Promise.all(resultsPromises)).filter((x) => x.title); + return results; + } + + override async fetchChapters(id: string): Promise { + const chapters: Chapter[] = []; + + const data = await (await this.request(`${this.url}${id}`)).text(); + + const $ = load(data); + + $("main div.post-content ol li").map((i, el) => { + const id = $(el).find("a").attr("href")!; + if (id && !id.includes(this.url)) { + const title = $(el).text()?.split(" ——")[0]; + chapters.push({ + id: id, + title: title?.trim(), + number: i + 1, + }); + } + }); + + return chapters; + } + + override async fetchPages(id: string): Promise { + return `No content able to read! You may download the novel here.`; + } +} diff --git a/anify-backend-recode/src/mappings/impl/manga/mangadex.ts b/anify-backend-recode/src/mappings/impl/manga/mangadex.ts new file mode 100644 index 0000000..6ac2b47 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/manga/mangadex.ts @@ -0,0 +1,165 @@ +import MangaProvider from "."; +import { wait } from "../../../helper"; +import { Format, Formats } from "../../../types/enums"; +import { Chapter, Page, Result } from "../../../types/types"; + +export default class MangaDex extends MangaProvider { + override rateLimit = 250; + override id = "mangadex"; + override url = "https://mangadex.org"; + + override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; + + private api = "https://api.mangadex.org"; + + override async search(query: string, format?: Format, year?: number): Promise { + const results: Result[] = []; + + let mangaList: any[] = []; + + for (let page = 0; page <= 1; page += 1) { + const uri = new URL("/manga", this.api); + uri.searchParams.set("title", query); + uri.searchParams.set("limit", "25"); + uri.searchParams.set("offset", String(25 * page).toString()); + uri.searchParams.set("order[relevance]", "desc"); + uri.searchParams.append("contentRating[]", "safe"); + uri.searchParams.append("contentRating[]", "suggestive"); + uri.searchParams.append("contentRating[]", "erotica"); + uri.searchParams.append("contentRating[]", "pornographic"); + uri.searchParams.append("includes[]", "cover_art"); + + const data = await (await this.request(uri.href)).json(); + // API rate limit + await wait(250); + + mangaList = [...mangaList, ...data.data]; + } + + for (let i = 0; i < mangaList.length; i++) { + const manga = mangaList[i]; + const attributes = manga.attributes; + const relationships = manga.relationships; + + const title = attributes.title["en"] ?? attributes.title["ja"] ?? attributes.title["ja-ro"] ?? attributes.title["ko"] ?? Object.values(attributes.title)[0]; + + const altTitles: string[] = attributes.altTitles.map((title: { [key: string]: string }) => { + return Object.values(title)[0]; + }); + + const id = manga.id; + let img = null; + relationships.map((element: { id: string; type: string; related: string; attributes: { [key: string]: string } }) => { + if (element.type === "cover_art") { + img = `${this.url}/covers/${id}/${element.id}.jpg.512.jpg`; + } + }); + + const formatString: string = manga.type.toUpperCase(); + const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + results.push({ + id, + title: title, + altTitles: altTitles, + img, + format, + year: attributes.year, + providerId: this.id, + }); + } + return results; + } + + override async fetchChapters(id: string): Promise { + const chapterList: Chapter[] = []; + + for (let page = 0, run = true; run; page++) { + const request = await this.request(`${this.api}/manga/${id}/feed?limit=500&translatedLanguage%5B%5D=en&includes[]=scanlation_group&includes[]=user&order[volume]=desc&order[chapter]=desc&offset=${500 * page}&contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic`).catch((err) => { + return null; + }); + if (!request) { + run = false; + break; + } + + await wait(250); + + const data = await request.json(); + + if (!data || !data.result) { + run = false; + break; + } + + if (data.result === "error") { + const error = data.errors[0]; + throw new Error(error.detail); + } + + const chapters: Chapter[] = []; + Object.keys(data.data).map((chapter) => { + const curChapter = data.data[chapter]; + const id = curChapter.id; + let title = ""; + + if (curChapter.attributes.volume) { + title += "Vol. " + this.padNum(curChapter.attributes.volume, 2) + " "; + } + if (curChapter.attributes.chapter) { + title += "Ch. " + this.padNum(curChapter.attributes.chapter, 2) + " "; + } + + let canPush = true; + for (let i = 0; i < chapters.length; i++) { + if (chapters[i].title?.trim() === title?.trim()) { + canPush = false; + } + } + + if (canPush) { + chapters.push({ + id, + title: title?.trim(), + number: Number(curChapter.attributes.chapter), + updatedAt: new Date(curChapter.attributes.updatedAt ?? 0).getTime(), + }); + } + }); + + chapters.length > 0 ? chapterList.push(...chapters) : (run = false); + } + + return chapterList; + } + + override async fetchPages(id: string): Promise { + const req = await this.request(`${this.api}/at-home/server/${id}`).catch((err) => { + return null; + }); + + if (!req) { + return []; + } + + await wait(250); + + const data = await req.json(); + + const baseUrl = data.baseUrl; + const hash = data.chapter.hash; + + const pages: Page[] = []; + for (let i = 0; i < data.chapter.data.length; i++) { + const url = `${baseUrl}/data/${hash}/${data.chapter.data[i]}`; + pages.push({ + url: url, + index: i, + headers: { + Referer: this.url, + }, + }); + } + return pages; + } +} diff --git a/anify-backend-recode/src/mappings/impl/manga/mangasee.ts b/anify-backend-recode/src/mappings/impl/manga/mangasee.ts new file mode 100644 index 0000000..244b78f --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/manga/mangasee.ts @@ -0,0 +1,128 @@ +import { load } from "cheerio"; +import MangaProvider from "."; +import { stringSearch } from "../../../helper/title"; +import { Format } from "../../../types/enums"; +import { Chapter, Page, Result } from "../../../types/types"; + +export default class MangaSee extends MangaProvider { + override rateLimit = 250; + override id = "mangasee"; + override url = "https://mangasee123.com"; + + override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; + + override async search(query: string, format?: Format, year?: number): Promise { + const list = await this.getMangaList(); + const results: Result[] = []; + + for (let i = 0; i < list.length; i++) { + if (stringSearch(list[i].s, query) >= 0.875) { + results.push({ + title: list[i].s, + id: `/manga/${list[i].i}`, + altTitles: list[i].a, + year: 0, + img: null, + format: Format.UNKNOWN, + providerId: this.id, + }); + } + } + return results; + } + + override async fetchChapters(id: string): Promise { + const data = await this.request(`${this.url}${id}`); + const chapters: Chapter[] = []; + + const $ = load(await data.text()); + + const mangaId = id.split("/manga/")[1]; + const contentScript = $("body > script:nth-child(16)").get()[0].children[0] as any; + + const chaptersData = this.processScriptTagVariable(contentScript["data"], "vm.Chapters = "); + chaptersData?.map((i: { [x: string]: any }) => { + chapters.push({ + id: `/read-online/${mangaId}-chapter-${this.processChapterNumber(i["Chapter"])}`, + title: `${i["ChapterName"] && i["ChapterName"].length > 0 ? i["ChapterName"] : `Chapter ${this.processChapterNumber(i["Chapter"])}`}`, + number: parseInt(this.processChapterNumber(i["Chapter"])), + updatedAt: new Date(i["Date"]).getTime(), + }); + }); + + return chapters; + } + + override async fetchPages(id: string): Promise { + const data = await this.request(`${this.url}${id}-page-1.html`); + + const images: Page[] = []; + + const $ = load(await data.text()); + + const chapterScript = $("body > script:nth-child(19)").get()[0].children[0] as any; + const curChapter = this.processScriptTagVariable(chapterScript["data"], "vm.CurChapter = "); + const imageHost = this.processScriptTagVariable(chapterScript["data"], "vm.CurPathName = "); + const curChapterLength = Number(curChapter["Page"]); + + for (let i = 0; i < curChapterLength; i++) { + const chapter = this.processChapterForImageUrl(id.replace(/[^0-9.]/g, "")); + const page = `${i + 1}`.padStart(3, "0"); + const mangaId = id.split("-chapter-", 1)[0].split("/read-online/")[1]; + const imagePath = `https://${imageHost}/manga/${mangaId}/${chapter}-${page}.png`; + + images.push({ + url: imagePath, + index: i, + headers: { + Referer: this.url, + }, + }); + } + + return images; + } + + private processScriptTagVariable = (script: string, variable: string) => { + const chopFront = script.substring(script.search(variable) + variable.length, script.length); + const chapters = JSON.parse(chopFront.substring(0, chopFront.search(";"))); + + return chapters; + }; + + private processChapterNumber = (chapter: string): string => { + const decimal = chapter.substring(chapter.length - 1, chapter.length); + chapter = chapter.replace(chapter[0], "").slice(0, -1); + if (decimal == "0") return `${+chapter}`; + + if (chapter.startsWith("0")) chapter = chapter.replace(chapter[0], ""); + + return `${+chapter}.${decimal}`; + }; + + private processChapterForImageUrl = (chapter: string): string => { + if (!chapter.includes(".")) return chapter.padStart(4, "0"); + + const values = chapter.split("."); + const pad = values[0].padStart(4, "0"); + + return `${pad}.${values[1]}`; + }; + + private async getMangaList(): Promise { + const req = await this.request(`${this.url}/_search.php`, { + method: "POST", + headers: { + Referer: this.url, + }, + }); + const data: [SearchResult] = await req.json(); + return data; + } +} + +interface SearchResult { + i: string; // image + s: string; // Main title + a: [string]; // Alternative titles +} diff --git a/anify-backend-recode/src/mappings/impl/meta/mal.ts b/anify-backend-recode/src/mappings/impl/meta/mal.ts index 783e9e5..c68e0b5 100644 --- a/anify-backend-recode/src/mappings/impl/meta/mal.ts +++ b/anify-backend-recode/src/mappings/impl/meta/mal.ts @@ -14,81 +14,37 @@ export default class MALMeta extends MetaProvider { override async search(query: string, format?: Format | undefined, year?: number | undefined): Promise { const results: Result[] = []; - const anime = await (await this.request(`${this.api}/anime?q=${encodeURIComponent(query)}&sfw`, {}, true)).json(); - const manga = await (await this.request(`${this.api}/manga?q=${encodeURIComponent(query)}&sfw`, {}, true)).json(); - - for (const data of anime.data) { - results.push({ - id: String(data.mal_id), - altTitles: data.title_synonyms?.filter((s: string) => s?.length) ?? [], - format: data.type?.toLowerCase() === "tv" ? Format.TV : data.type?.toLowerCase() === "movie" ? Format.MOVIE : data.type?.toLowerCase() === "ova" ? Format.OVA : data.type?.toLowerCase() === "special" ? Format.SPECIAL : data.type?.toLowerCase() === "ona" ? Format.ONA : data.type?.toLowerCase() === "music" ? Format.MUSIC : data.type?.toLowerCase() === "manga" ? Format.MANGA : data.type?.toLowerCase() === "novel" ? Format.NOVEL : data.type?.toLowerCase() === "lightnovel" ? Format.NOVEL : data.type?.toLowerCase() === "oneshot" ? Format.ONE_SHOT : data.type?.toLowerCase() === "doujin" ? Format.MANGA : data.type?.toLowerCase() === "manhwa" ? Format.MANGA : data.type?.toLowerCase() === "manhua" ? Format.MANGA : Format.UNKNOWN, - img: data.images?.jpg?.large_image_url ?? data.images?.jpg?.image_url ?? data.images?.jpg?.small_image_url ?? null, - providerId: this.id, - title: data.title ?? data.title_english ?? data.title_japanese ?? "", - year: data.year ? data.year : data.published ? (data.published.from ? new Date(data.published).getFullYear() : data.published.prop ? data.published.prop.from?.year : null) : null, - }); - } - - for (const data of manga.data) { - results.push({ - id: String(data.mal_id), - altTitles: data.title_synonyms?.filter((s: string) => s?.length) ?? [], - format: data.type?.toLowerCase() === "tv" ? Format.TV : data.type?.toLowerCase() === "movie" ? Format.MOVIE : data.type?.toLowerCase() === "ova" ? Format.OVA : data.type?.toLowerCase() === "special" ? Format.SPECIAL : data.type?.toLowerCase() === "ona" ? Format.ONA : data.type?.toLowerCase() === "music" ? Format.MUSIC : data.type?.toLowerCase() === "manga" ? Format.MANGA : data.type?.toLowerCase() === "novel" ? Format.NOVEL : data.type?.toLowerCase() === "lightnovel" ? Format.NOVEL : data.type?.toLowerCase() === "oneshot" ? Format.ONE_SHOT : data.type?.toLowerCase() === "doujin" ? Format.MANGA : data.type?.toLowerCase() === "manhwa" ? Format.MANGA : data.type?.toLowerCase() === "manhua" ? Format.MANGA : Format.UNKNOWN, - img: data.images?.jpg?.large_image_url ?? data.images?.jpg?.image_url ?? data.images?.jpg?.small_image_url ?? null, - providerId: this.id, - title: data.title ?? data.title_english ?? data.title_japanese ?? "", - year: data.year ? data.year : data.published ? (data.published.from ? new Date(data.published).getFullYear() : data.published.prop ? data.published.prop.from?.year : null) : null, - }); + try { + const anime = await (await this.request(`${this.api}/anime?q=${encodeURIComponent(query)}&sfw`, {}, true)).json(); + const manga = await (await this.request(`${this.api}/manga?q=${encodeURIComponent(query)}&sfw`, {}, true)).json(); + + for (const data of anime.data) { + results.push({ + id: String(data.mal_id), + altTitles: data.title_synonyms?.filter((s: string) => s?.length) ?? [], + format: data.type?.toLowerCase() === "tv" ? Format.TV : data.type?.toLowerCase() === "movie" ? Format.MOVIE : data.type?.toLowerCase() === "ova" ? Format.OVA : data.type?.toLowerCase() === "special" ? Format.SPECIAL : data.type?.toLowerCase() === "ona" ? Format.ONA : data.type?.toLowerCase() === "music" ? Format.MUSIC : data.type?.toLowerCase() === "manga" ? Format.MANGA : data.type?.toLowerCase() === "novel" ? Format.NOVEL : data.type?.toLowerCase() === "lightnovel" ? Format.NOVEL : data.type?.toLowerCase() === "oneshot" ? Format.ONE_SHOT : data.type?.toLowerCase() === "doujin" ? Format.MANGA : data.type?.toLowerCase() === "manhwa" ? Format.MANGA : data.type?.toLowerCase() === "manhua" ? Format.MANGA : Format.UNKNOWN, + img: data.images?.jpg?.large_image_url ?? data.images?.jpg?.image_url ?? data.images?.jpg?.small_image_url ?? null, + providerId: this.id, + title: data.title ?? data.title_english ?? data.title_japanese ?? "", + year: data.year ? data.year : data.published ? (data.published.from ? new Date(data.published).getFullYear() : data.published.prop ? data.published.prop.from?.year : null) : null, + }); + } + + for (const data of manga.data) { + results.push({ + id: String(data.mal_id), + altTitles: data.title_synonyms?.filter((s: string) => s?.length) ?? [], + format: data.type?.toLowerCase() === "tv" ? Format.TV : data.type?.toLowerCase() === "movie" ? Format.MOVIE : data.type?.toLowerCase() === "ova" ? Format.OVA : data.type?.toLowerCase() === "special" ? Format.SPECIAL : data.type?.toLowerCase() === "ona" ? Format.ONA : data.type?.toLowerCase() === "music" ? Format.MUSIC : data.type?.toLowerCase() === "manga" ? Format.MANGA : data.type?.toLowerCase() === "novel" ? Format.NOVEL : data.type?.toLowerCase() === "lightnovel" ? Format.NOVEL : data.type?.toLowerCase() === "oneshot" ? Format.ONE_SHOT : data.type?.toLowerCase() === "doujin" ? Format.MANGA : data.type?.toLowerCase() === "manhwa" ? Format.MANGA : data.type?.toLowerCase() === "manhua" ? Format.MANGA : Format.UNKNOWN, + img: data.images?.jpg?.large_image_url ?? data.images?.jpg?.image_url ?? data.images?.jpg?.small_image_url ?? null, + providerId: this.id, + title: data.title ?? data.title_english ?? data.title_japanese ?? "", + year: data.year ? data.year : data.published ? (data.published.from ? new Date(data.published).getFullYear() : data.published.prop ? data.published.prop.from?.year : null) : null, + }); + } + + return results; + } catch (e) { + return undefined; } - - return results; } } - -type JikanResponse = { - mal_id: number; - url: string; - title: string; - title_english: string | null; - title_japanese: string | null; - title_synonyms: string[]; - type: string; - status: string; - synopsis: string | null; - images: { - jpg: { - image_url: string | null; - small_image_url: string | null; - large_image_url: string | null; - }; - webp: { - image_url: string | null; - small_image_url: string | null; - large_image_url: string | null; - }; - }; - duration: string; - episodes: number | null; - popularity: number | null; - score: number | null; - season: string; - year: number | null; - genres: { name: string }[]; - trailer: { - youtube_id: string | null; - url: string | null; - embed_url: string | null; - images: { - image_url: string | null; - small_image_url: string | null; - medium_image_url: string | null; - large_image_url: string | null; - maximum_image_url: string | null; - }; - }; - approved: boolean; - titles: { - type: string; - title: string; - }[]; -}; diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend-recode/src/mappings/index.ts index bf38ccb..3d8563f 100644 --- a/anify-backend-recode/src/mappings/index.ts +++ b/anify-backend-recode/src/mappings/index.ts @@ -8,10 +8,16 @@ import BaseProvider from "./impl/base"; import AniListBase from "./impl/base/anilist"; import InformationProvider from "./impl/information"; import AniList from "./impl/information/anilist"; +import ComicKInfo from "./impl/information/comick"; import Kitsu from "./impl/information/kitsu"; import MAL from "./impl/information/mal"; +import MangaDexInfo from "./impl/information/mangadex"; import TVDB from "./impl/information/tvdb"; import MangaProvider from "./impl/manga"; +import ComicK from "./impl/manga/comick"; +import JNovels from "./impl/manga/jnovels"; +import MangaDex from "./impl/manga/mangadex"; +import MangaSee from "./impl/manga/mangasee"; import MetaProvider from "./impl/meta"; import AniListMeta from "./impl/meta/anilist"; import KitsuMeta from "./impl/meta/kitsu"; @@ -28,7 +34,7 @@ const animeProviders: Record = ANIME_PROVIDERS.reduce( {} as Record, ); -const MANGA_PROVIDERS: MangaProvider[] = []; +const MANGA_PROVIDERS: MangaProvider[] = [new ComicK(), new MangaDex(), new MangaSee(), new JNovels()]; const mangaProviders: Record = MANGA_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; @@ -37,7 +43,7 @@ const mangaProviders: Record = MANGA_PROVIDERS.reduce( {} as Record, ); -const INFORMATION_PROVIDERS: InformationProvider[] = [new AniList(), new Kitsu(), new MAL(), new TVDB()]; +const INFORMATION_PROVIDERS: InformationProvider[] = [new AniList(), new Kitsu(), new MAL(), new TVDB(), new ComicKInfo(), new MangaDexInfo()]; const infoProviders: Record> = INFORMATION_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; From dcc2f468c63d115ab0b8f28f6afb542c81820874 Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 6 Sep 2023 14:53:51 -0400 Subject: [PATCH 11/77] Searching --- anify-backend-recode/db.sqlite | Bin 61440 -> 176128 bytes anify-backend-recode/package.json | 4 +- anify-backend-recode/src/env.ts | 4 - anify-backend-recode/src/index.ts | 21 +- anify-backend-recode/src/lib/impl/search.ts | 18 ++ .../src/mappings/impl/base/anilist.ts | 217 ++++++++++++++++++ .../src/mappings/impl/base/index.ts | 4 + .../src/mappings/impl/manga/novelupdates.ts | 120 ++++++++++ anify-backend-recode/src/mappings/index.ts | 3 +- anify-backend-recode/src/server/impl/info.ts | 44 ++++ .../src/server/impl/search.ts | 65 ++++++ anify-backend-recode/src/server/index.ts | 43 ++++ .../src/worker/impl/search.ts | 14 ++ anify-backend-recode/src/worker/index.ts | 2 + 14 files changed, 545 insertions(+), 14 deletions(-) create mode 100644 anify-backend-recode/src/lib/impl/search.ts create mode 100644 anify-backend-recode/src/mappings/impl/manga/novelupdates.ts create mode 100644 anify-backend-recode/src/server/impl/info.ts create mode 100644 anify-backend-recode/src/server/impl/search.ts create mode 100644 anify-backend-recode/src/server/index.ts create mode 100644 anify-backend-recode/src/worker/impl/search.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 27950dbc4d13e538cfedd1639cec5dbb2e712de1..72c0658b6a72f41e6bcddd9e0a70866cd15272b4 100644 GIT binary patch literal 176128 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

CfxWqAm=y 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 delta 93 zcmZp8z}4`8d4e>n83O|Y|3n3QMzf6xOZd4M`F{fi7J4)tSo1$lAid+OkK%hnnz04t>(I{*Lx diff --git a/anify-backend-recode/package.json b/anify-backend-recode/package.json index d0b1dde..2c4cde9 100644 --- a/anify-backend-recode/package.json +++ b/anify-backend-recode/package.json @@ -22,10 +22,12 @@ "typescript": "^5.0.0" }, "dependencies": { + "@extractus/article-extractor": "^8.0.2", "cheerio": "^1.0.0-rc.12", "colors": "^1.4.0", "crypto-js": "^4.1.1", "dotenv": "^16.3.1", - "eventemitter2": "latest" + "eventemitter2": "latest", + "ioredis": "^5.3.2" } } diff --git a/anify-backend-recode/src/env.ts b/anify-backend-recode/src/env.ts index 4a18604..7be049d 100644 --- a/anify-backend-recode/src/env.ts +++ b/anify-backend-recode/src/env.ts @@ -1,8 +1,6 @@ // All environment variables. export const env = { PORT: Number(process.env.PORT) || 3000, - DATABASE_TYPE: process.env.DATABASE_TYPE || "postgres", - DATABASE_URL: process.env.DATABASE_URL, NINEANIME_RESOLVER: process.env.NINEANIME_RESOLVER, NINEANIME_KEY: process.env.NINEANIME_KEY, REDIS_URL: process.env.REDIS_URL, @@ -12,8 +10,6 @@ export const env = { API_KEY_WHITELIST: process.env.API_KEY_WHITELIST?.split(",") || [], CENSYS_ID: process.env.CENSYS_ID, CENSYS_SECRET: process.env.CENSYS_SECRET, - SIMKL_CLIENT_ID: process.env.SIMKL_CLIENT_ID, - SIMKL_CLIENT_SECRET: process.env.SIMKL_CLIENT_SECRET, USE_MIXDROP: process.env.USE_MIXDROP === "true" || false, MIXDROP_EMAIL: process.env.MIXDROP_EMAIL, MIXDROP_KEY: process.env.MIXDROP_KEY, diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 011e9df..f3cad55 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -2,20 +2,15 @@ import dotenv from "dotenv"; dotenv.config(); import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; -import { loadMapping } from "./lib/impl/mappings"; -import { Type } from "./types/enums"; +import { MediaStatus } from "./types/enums"; import { init } from "./database"; import emitter, { Events } from "./lib"; import { get } from "./database/impl/get"; import queues from "./worker"; -import { deleteEntry } from "./database/impl/delete"; -import { mangaProviders } from "./mappings"; +import { start } from "./server"; before().then(async (_) => { - if (await get("132182")) await deleteEntry("132182"); - await loadMapping({ id: "132182", type: Type.MANGA }).then(console.log); - - //mangaProviders.mangasee.fetchPages("/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-chapter-1").then(console.log); + await start(); }); async function before() { @@ -31,6 +26,16 @@ async function before() { } }); + emitter.on(Events.COMPLETED_SEARCH_LOAD, (data) => { + for (let i = 0; i < data.length; i++) { + if (data[i].status === MediaStatus.NOT_YET_RELEASED) { + continue; + } + queues.mappingQueue.add({ id: data[i].id, type: data[i].type }); + } + }); + queues.mappingQueue.start(); queues.createEntry.start(); + queues.searchQueue.start(); } diff --git a/anify-backend-recode/src/lib/impl/search.ts b/anify-backend-recode/src/lib/impl/search.ts new file mode 100644 index 0000000..81f39af --- /dev/null +++ b/anify-backend-recode/src/lib/impl/search.ts @@ -0,0 +1,18 @@ +import emitter, { Events } from ".."; +import { search } from "../../database/impl/search"; +import { baseProviders } from "../../mappings"; +import { Format, Type } from "../../types/enums"; + +export const loadSearch = async (data: { query: string; type: Type; formats: Format[] }) => { + // First check if exists in database + const existing = await search(data.query, data.type, data.formats, 1, 15); + if (existing.length > 0) { + await emitter.emitAsync(Events.COMPLETED_SEARCH_LOAD, existing); + return existing; + } + + const result = await baseProviders.anilist.search(data.query, data.type, data.formats, 0, 10); + + await emitter.emitAsync(Events.COMPLETED_SEARCH_LOAD, result); + return result; +}; diff --git a/anify-backend-recode/src/mappings/impl/base/anilist.ts b/anify-backend-recode/src/mappings/impl/base/anilist.ts index 8afe36d..6b45f5c 100644 --- a/anify-backend-recode/src/mappings/impl/base/anilist.ts +++ b/anify-backend-recode/src/mappings/impl/base/anilist.ts @@ -8,6 +8,223 @@ export default class AniListBase extends BaseProvider { private api = "https://graphql.anilist.co"; + override async search(query: string, type: Type, formats: Format[], page: number, perPage: number): Promise { + const aniListArgs: { query: string; variables: { [key: string]: any } } = { + query: ` + query ($page: Int, $perPage: Int, $search: String, $type: MediaType, $format: [MediaFormat]) { + Page(page: $page, perPage: $perPage) { + pageInfo { + total + currentPage + lastPage + hasNextPage + perPage + } + media(type: $type, format_in: $format, search: $search) { + ${this.query} + } + } + } + `, + variables: { + search: query, + type: type, + format: formats, + page: page, + perPage: perPage, + }, + }; + + const req = await this.request( + this.api, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + origin: "graphql.anilist.co", + }, + body: JSON.stringify(aniListArgs), + }, + true, + ); + const json = await req?.json(); + const media = json.data.Page.media; + + if (type === Type.ANIME) { + return media.map((data: Media) => { + const artwork: Artwork[] = []; + + if (data.coverImage.large) + artwork.push({ + type: "poster", + img: data.coverImage.large, + providerId: this.id, + }); + if (data.coverImage.extraLarge) + artwork.push({ + type: "poster", + img: data.coverImage.extraLarge, + providerId: this.id, + }); + if (data.bannerImage) + artwork.push({ + type: "banner", + img: data.bannerImage, + providerId: this.id, + }); + + const characters: Character[] = []; + const relations: Relations[] = []; + + for (const character of data.characters.edges) { + if (characters.length > 10) break; + const aliases: string[] = []; + + for (const alias of character.node.name.alternative) { + aliases.push(alias); + } + aliases.push(character.node.name.full); + + characters.push({ + voiceActor: { + name: character.voiceActors[0]?.name?.full ?? null, + image: character.voiceActors[0]?.image?.large ?? null, + }, + image: character.node.image.large, + name: character.node.name.full, + }); + } + + for (const relation of data.relations.edges) { + relations.push({ + id: String(relation.node.id), + format: relation.node.format, + relationType: relation.relationType, + title: relation.node.title, + type: relation.node.type, + }); + } + + return { + id: String(data.id), + title: { + english: data.title.english ?? null, + romaji: data.title.romaji ?? null, + native: data.title.native ?? null, + }, + trailer: null, + currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, + duration: data.duration ?? null, + coverImage: data.coverImage.extraLarge ?? null, + bannerImage: data.bannerImage ?? null, + popularity: Number(data.popularity), + synonyms: data.synonyms ?? [], + totalEpisodes: data.episodes ?? 0, + color: null, + status: data.status, + season: data.season as Season, + genres: (data.genres as Genres[]) ?? [], + rating: data.meanScore ? data.meanScore / 10 : null, + description: data.description ?? null, + format: data.format, + year: data.seasonYear ?? data.startDate?.year ?? null, + type: data.type, + countryOfOrigin: data.countryOfOrigin ?? null, + tags: data.tags.map((tag) => { + return tag.name; + }), + artwork: artwork, + relations: relations, + characters: characters, + } as AnimeInfo; + }); + } else { + return media.map((data: Media) => { + const artwork: Artwork[] = []; + + if (data.coverImage.large) + artwork.push({ + type: "poster", + img: data.coverImage.large, + providerId: this.id, + }); + if (data.coverImage.extraLarge) + artwork.push({ + type: "poster", + img: data.coverImage.extraLarge, + providerId: this.id, + }); + if (data.bannerImage) + artwork.push({ + type: "banner", + img: data.bannerImage, + providerId: this.id, + }); + + const characters: Character[] = []; + const relations: Relations[] = []; + + for (const character of data.characters.edges) { + if (characters.length > 10) break; + const aliases: string[] = []; + + for (const alias of character.node.name.alternative) { + aliases.push(alias); + } + aliases.push(character.node.name.full); + + characters.push({ + voiceActor: { + name: character.voiceActors[0]?.name?.full ?? null, + image: character.voiceActors[0]?.image?.large ?? null, + }, + image: character.node.image.large, + name: character.node.name.full, + }); + } + + for (const relation of data.relations.edges) { + relations.push({ + id: String(relation.node.id), + format: relation.node.format, + relationType: relation.relationType, + title: relation.node.title, + type: relation.node.type, + }); + } + + return { + id: String(data.id), + title: { + english: data.title.english ?? null, + romaji: data.title.romaji ?? null, + native: data.title.native ?? null, + }, + coverImage: data.coverImage.extraLarge ?? null, + bannerImage: data.bannerImage ?? null, + popularity: Number(data.popularity), + synonyms: data.synonyms ?? [], + totalChapters: data.chapters ?? 0, + totalVolumes: data.volumes ?? 0, + color: null, + status: data.status, + genres: (data.genres as Genres[]) ?? [], + rating: data.meanScore ? data.meanScore / 10 : null, + description: data.description ?? null, + format: data.format, + year: data.seasonYear ?? data.startDate?.year ?? null, + type: data.type, + countryOfOrigin: data.countryOfOrigin ?? null, + tags: data.tags.map((tag) => tag.name), + artwork: artwork, + characters: characters, + relations: relations, + } as MangaInfo; + }); + } + } + override async searchAdvanced(query: string, type: Type, formats: Format[], page: number, perPage: number, genres: Genres[] = [], genresExcluded: Genres[] = [], year = 0, tags: string[] = [], tagsExcluded: string[] = []): Promise { const aniListArgs: { query: string; variables: { [key: string]: any } } = { query: ` diff --git a/anify-backend-recode/src/mappings/impl/base/index.ts b/anify-backend-recode/src/mappings/impl/base/index.ts index 8989ce6..cb52c0f 100644 --- a/anify-backend-recode/src/mappings/impl/base/index.ts +++ b/anify-backend-recode/src/mappings/impl/base/index.ts @@ -9,6 +9,10 @@ export default abstract class BaseProvider { public providerType: ProviderType = ProviderType.BASE; public customProxy: string | undefined; + async search(query: string, type: Type, formats: Format[], page: number, perPage: number): Promise { + return undefined; + } + async searchAdvanced(query: string, type: Type, formats: Format[], page: number, perPage: number, genres: Genres[] = [], genresExcluded: Genres[] = [], year = 0, tags: string[] = [], tagsExcluded: string[] = []): Promise { return undefined; } diff --git a/anify-backend-recode/src/mappings/impl/manga/novelupdates.ts b/anify-backend-recode/src/mappings/impl/manga/novelupdates.ts new file mode 100644 index 0000000..13538bb --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/manga/novelupdates.ts @@ -0,0 +1,120 @@ +import { load } from "cheerio"; +import { extract } from "@extractus/article-extractor"; +import MangaProvider from "."; +import { Format } from "../../../types/enums"; +import { Chapter, Page, Result } from "../../../types/types"; + +export default class NovelUpdates extends MangaProvider { + override rateLimit = 1000; + override id = "novelupdates"; + override url = "https://www.novelupdates.com"; + + override formats: Format[] = [Format.NOVEL]; + + override async search(query: string, format?: Format, year?: number): Promise { + const results: Result[] = []; + + const searchData = await this.request( + `${this.url}/series-finder/?sf=1&sh=${encodeURIComponent(query)}&nt=2443,26874,2444&ge=280&sort=sread&order=desc`, + { + method: "GET", + headers: { + Referer: this.url, + }, + }, + true, + ); + + const data = await searchData.text(); + + const $ = load(data); + + $("div.search_main_box_nu").each((_, el) => { + const img = $(el).find("div.search_img_nu img").attr("src"); + const title = $(el).find("div.search_body_nu div.search_title a").text(); + const id = $(el).find("div.search_body_nu div.search_title a").attr("href")?.split(this.url)[1]; + + results.push({ + id: id!, + title: title!, + img: img!, + altTitles: [], + format: Format.NOVEL, + providerId: this.id, + year: 0, + }); + }); + + return results; + } + + override async fetchChapters(id: string): Promise { + const chapters: Chapter[] = []; + + const data = await ( + await this.request( + `${this.url}${id}`, + { + headers: { + Cookie: "_ga=;", + }, + }, + true, + ) + ).text(); + + const $ = load(data); + + const postId = $("input#mypostid").attr("value"); + + const chapterData = ( + await ( + await this.request( + `${this.url}/wp-admin/admin-ajax.php`, + { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + Cookie: "_ga=;", + }, + body: `action=nd_getchapters&mypostid=${postId}&mypostid2=0`, + }, + true, + ) + ).text() + ).substring(1); + + const $$ = load(chapterData); + $$("li.sp_li_chp a[data-id]").each((index, el) => { + const id = $$(el).attr("data-id"); + const title = $$(el).find("span").text(); + + chapters.push({ + id: id!, + title: title!, + number: index + 1, + }); + }); + + return chapters; + } + + override async fetchPages(id: string): Promise { + const data = await ( + await this.request( + `${this.url}/extnu/${id}/`, + { + method: "GET", + headers: { + Cookie: "_ga=;", + }, + redirect: "follow", + }, + true, + ) + ).text(); + + const article = await extract(data); + return article?.content; + } +} diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend-recode/src/mappings/index.ts index 3d8563f..ec0c44a 100644 --- a/anify-backend-recode/src/mappings/index.ts +++ b/anify-backend-recode/src/mappings/index.ts @@ -18,6 +18,7 @@ import ComicK from "./impl/manga/comick"; import JNovels from "./impl/manga/jnovels"; import MangaDex from "./impl/manga/mangadex"; import MangaSee from "./impl/manga/mangasee"; +import NovelUpdates from "./impl/manga/novelupdates"; import MetaProvider from "./impl/meta"; import AniListMeta from "./impl/meta/anilist"; import KitsuMeta from "./impl/meta/kitsu"; @@ -34,7 +35,7 @@ const animeProviders: Record = ANIME_PROVIDERS.reduce( {} as Record, ); -const MANGA_PROVIDERS: MangaProvider[] = [new ComicK(), new MangaDex(), new MangaSee(), new JNovels()]; +const MANGA_PROVIDERS: MangaProvider[] = [new ComicK(), new MangaDex(), new MangaSee(), new JNovels(), new NovelUpdates()]; const mangaProviders: Record = MANGA_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; diff --git a/anify-backend-recode/src/server/impl/info.ts b/anify-backend-recode/src/server/impl/info.ts new file mode 100644 index 0000000..22c8b60 --- /dev/null +++ b/anify-backend-recode/src/server/impl/info.ts @@ -0,0 +1,44 @@ +import { get } from "../../database/impl/get"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const id = paths[1] ?? url.searchParams.get("id") ?? null; + if (!id) { + return new Response(JSON.stringify({ error: "No ID provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const data = await get(String(id)); + if (!data) { + return new Response(JSON.stringify({ error: "No data found." }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + } + + return new Response(JSON.stringify(data), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + method: "GET", + path: "/info", + handler, +}; + +export default route; diff --git a/anify-backend-recode/src/server/impl/search.ts b/anify-backend-recode/src/server/impl/search.ts new file mode 100644 index 0000000..11404c2 --- /dev/null +++ b/anify-backend-recode/src/server/impl/search.ts @@ -0,0 +1,65 @@ +import queues from "../../worker"; +import { search } from "../../database/impl/search"; +import { Format, Type } from "../../types/enums"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const validTypes = ["anime", "manga", "novel"]; + + const type = paths[1] ?? url.searchParams.get("type") ?? null; + if (!type) { + return new Response(JSON.stringify({ error: "No type provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } else if (!validTypes.includes(type.toLowerCase())) { + return new Response(JSON.stringify({ error: "Invalid type provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const query = decodeURIComponent(paths[2] ?? url.searchParams.get("query") ?? ""); + if (!query || query.length === 0) { + return new Response(JSON.stringify({ error: "No query provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const data = await search(query, type.toUpperCase() as Type, formats, 0, 20); + if (data.length === 0) { + queues.searchQueue.add({ type: type.toUpperCase() as Type, query: query, formats: formats }); + + return new Response(JSON.stringify([]), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + + return new Response(JSON.stringify(data), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + method: "GET", + path: "/search", + handler, +}; + +export default route; diff --git a/anify-backend-recode/src/server/index.ts b/anify-backend-recode/src/server/index.ts new file mode 100644 index 0000000..a2c9777 --- /dev/null +++ b/anify-backend-recode/src/server/index.ts @@ -0,0 +1,43 @@ +import { readdirSync } from "node:fs"; +import { join } from "node:path"; + +import Redis from "ioredis"; + +import colors from "colors"; + +import { env } from "../env"; + +export const start = async () => { + const redis = new Redis((env.REDIS_URL as string) || "redis://localhost:6379"); + const cacheTime = env.REDIS_CACHE_TIME; + + const whitelist = env.API_KEY_WHITELIST; + + Bun.serve({ + port: env.PORT, + async fetch(req: Request) { + const url = new URL(req.url); + if (url.pathname === "/") return new Response("Welcome to Anify API! 🎉 Documentation can be viewed at https://docs.anify.tv. Join our Discord https://anify.tv/discord for more information.", { headers: { "Content-Type": "application/json" } }); + + // Dynamically add routes + const routeFiles = readdirSync(join(__dirname, "./impl")); + for (const file of routeFiles) { + const routeModule = await import(join(__dirname, "./impl", file)); + const route = routeModule.default; + + if (route) { + const { method, path, handler } = route; + const pathName = url.pathname.split("/").slice(1)[0]; + + if (method === req.method && path === `/${pathName}`) { + return handler(req); + } + } + } + + return new Response(JSON.stringify({ error: "Not found" }), { status: 404, headers: { "Content-Type": "application/json" } }); + }, + }); + + console.log(colors.blue(`Server is now listening on ${env.PORT}`)); +}; diff --git a/anify-backend-recode/src/worker/impl/search.ts b/anify-backend-recode/src/worker/impl/search.ts new file mode 100644 index 0000000..dda72be --- /dev/null +++ b/anify-backend-recode/src/worker/impl/search.ts @@ -0,0 +1,14 @@ +import colors from "colors"; +import QueueExecutor from "../../lib/executor"; +import { Format, Type } from "../../types/enums"; +import { loadSearch } from "../../lib/impl/search"; + +const executor = new QueueExecutor<{ query: string; type: Type; formats: Format[] }>("search-executor") + .executor(async (data) => { + const media = await loadSearch(data); + return media; + }) + .callback((id) => console.debug(colors.green(`Finished searching for media ${id.query} via the database/AniList.`))) + .error((err, id) => console.error(colors.red(`Error occurred while searching for media via the database/AniList ${id.query}`), err)) + .interval(1000); +export default executor; diff --git a/anify-backend-recode/src/worker/index.ts b/anify-backend-recode/src/worker/index.ts index e916c08..28a626d 100644 --- a/anify-backend-recode/src/worker/index.ts +++ b/anify-backend-recode/src/worker/index.ts @@ -1,7 +1,9 @@ import mappingQueue from "./impl/mappings"; import createEntry from "./impl/entry"; +import searchQueue from "./impl/search"; export default { mappingQueue, createEntry, + searchQueue, }; From 661968741ad196b28659b1b5232f4a9e5e51b9bd Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 6 Sep 2023 15:02:26 -0400 Subject: [PATCH 12/77] Bug fixes to searching --- anify-backend-recode/db.sqlite | Bin 176128 -> 233472 bytes .../src/database/impl/search.ts | 1 + .../src/database/impl/searchAdvanced.ts | 1 + .../src/database/impl/seasonal.ts | 1 + anify-backend-recode/src/helper/index.ts | 2 ++ .../src/server/impl/search.ts | 4 ++-- 6 files changed, 7 insertions(+), 2 deletions(-) diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 72c0658b6a72f41e6bcddd9e0a70866cd15272b4..2155f928da7ad5c87587e6bc6b311c80e6280539 100644 GIT binary patch delta 22921 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 delta 143 zcmZozz}N7AYl1Yd69WT-HV}isL=AIBr;Q0q_(jqH8JYNQPi(Z= qp6bXvpKmiuz+Zb#pm~h^-xz>u1q0sjH-DSo{%t Promise, interval: numb export const averageMetric = (object: any) => { let average = 0, validCount = 0; + if (!object) return 0; + for (const [_, v] of Object.entries(object)) { if (v && typeof v === "number") { average += v; diff --git a/anify-backend-recode/src/server/impl/search.ts b/anify-backend-recode/src/server/impl/search.ts index 11404c2..98592e3 100644 --- a/anify-backend-recode/src/server/impl/search.ts +++ b/anify-backend-recode/src/server/impl/search.ts @@ -33,9 +33,9 @@ export const handler = async (req: Request): Promise => { const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - const data = await search(query, type.toUpperCase() as Type, formats, 0, 20); + const data = await search(query, (type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, formats, 0, 20); if (data.length === 0) { - queues.searchQueue.add({ type: type.toUpperCase() as Type, query: query, formats: formats }); + queues.searchQueue.add({ type: (type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, query: query, formats: formats }); return new Response(JSON.stringify([]), { status: 200, From f52e5404bb962bbb10da9413c93943110e3ea507 Mon Sep 17 00:00:00 2001 From: Eltik Date: Thu, 7 Sep 2023 09:05:06 -0400 Subject: [PATCH 13/77] Use different base providers --- anify-backend-recode/db.sqlite | Bin 233472 -> 233472 bytes .../src/database/impl/seasonal.ts | 229 +++++------------- anify-backend-recode/src/index.ts | 2 +- anify-backend-recode/src/lib/impl/mappings.ts | 101 +++----- .../src/mappings/impl/base/anilist.ts | 3 + .../src/mappings/impl/base/index.ts | 5 +- .../src/worker/impl/mappings.ts | 4 +- .../src/worker/impl/search.ts | 4 +- anify-backend/src/worker/search.ts | 4 +- 9 files changed, 97 insertions(+), 255 deletions(-) diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 2155f928da7ad5c87587e6bc6b311c80e6280539..55d6d24dff8f8630454b1f7d2cd35e840adce6e6 100644 GIT binary patch delta 2467 zcmb7`YitzP6~}#N0YAWATpngIw#Q=|4Bp4QAFgpQ#Bm5UfnYT$$bmaAd+_eeb{|v* zIbm%FsY$BV4AD*64{@p}RnoMvvucU@Aw_B{Cv8 zRY&`qoyWQNoO|y%|2voG8!pc`{HVEpq^hb)15_Y6*R7zD#dGt~E%k6qMY2^J-AK0F zzSWEfzw@XAv7@D)l3=v8Oh>DpKQ`+%UO9`JsWXF3jn8gIrPyp^NvN)#-*&x;6M0Ef z{XgDp^-sRZ?H1rjWxagC%H>nCsA!64vMj3^HfbNF_FsK{OKWJNV`E}0=M`NO%s5@v zMVk{i6-(s(Q&i{XfybXXeoWPh-!?oyaZ^Eg-@5tglMt!$LKN+b;gVEe53w~?O>5H~ zjnmQEW~!&BY1>SqMrwn|s4EAr4sx=rDZ+%4(XCv1GLgaKUNJF-Cnn&}^%9fC3G5_X zoNygu+&S+R$rW1VuLuRkU== zkl19__2V~N{MVQS`NK$Lmw$`l>(5+b9Fyr~!br%W^Jr+J7<5f;&!PwXzqhy5)5DJI z&;zcMv6#63H~Q;O2HM-Y=*rB?m6_)%(?1Q)Gp{hCkDLgb;h-7q*>s=NAN2NgU&`sH z!^t;k&!r3F!CTug9Gs>{zULHRQE2R%^y4_^!sX$dmrv4<;4F4mLZH9n6-SD?MIRZ* zu4|=}9j1&eS+D-a0f$LJ+MlBO{4eOI zIzj_xYV-_q#LHObBok*I!fpZQCz;^cxT8B{QKwpKG)|E@K~%{rdBoPnf>aR%w3{>< z)S1R`Jrfs=qW0Ly3;gL}fh;N14w5|^IY1VKi1uF$v~XSd|9@S{;s&&x&@WKcKJ)un z`M3N2jQl%Y|M0KvU-m!T`vDq#o8GXshKep%MVF)hEH|F`B)YRM5<@FxLDfcLwJUj8 zUqzd-17#BnC_A&$M3yw<P*~gBeS~23JTAg z25TkHXUCYSsWoSV`HYprX~Hcdo}3$^>SCOzYSMa7ipVRR##*7Lnt?*TIN{MFggb`% zHVL6MSv*R`8opJ8GRe_HIG2Xf2m0`q2podL&B? z5sl|HUIPuY71LBL!ImW9KjM85=bU1m9?Dtn1t*;*CkG*^7M4+Wlb~?&dT*HH71p*$ zdwry}#>si$Ys4dSb&+qZ_vh{| zT)F$quRpu?*5}Xsp!}PU4-f<1xn|pJ0mdM>{Si!Q8~z0xme7 z3vG|2aXz2H1uG9X59J&S_8+(!_S|sCBGVsIopld8W8?HGW8Cw|f=;!CqQojJ7m8A} z*$$6GOUKRyr5j39d9Je;`8PW2$bw15xp1;mhIhfrt!^KxuJEG8syfDopb3V6b;D8( z(=u4qz%p6<0PP4=<{-b)cBSs_H8vGXP;Az=RoT+9ZcD1k>Y8C;MVBG0Pz9lJH<`C6 zrbf`@6c=Rd?FF=xd}>h}$-h3L>d3)v)ZhGdm07n#6U3k{!u}lfw|%7#_ur%mzDpVR zH43}qcvjT7|IuA&DG4GNuUWR<-!aIBZKyg=&~9}4>g$`H4kjLs1Q2}DM1TfhGZ1{v zYy}#DZvfkX?Z6IT3$PPt0(Jqrfo5P2&;qmqZ9oj5fp#F!=MJC~=mPcugL~n00N4-o l0Np?w2m(q1DS!nyfCofC0HS~d$bhz3dIMc|bCIhp{{}f&;pPAU delta 2149 zcmbVNYfKzf6yDi^vQU=G8e2*zaG55xS{8P8c4l``Yq#$gEdni3g7)t2Wp`kA24`j= z6e(<9#@bq?;`oZi#z&*k6i7=GYvO}~t_d0o_5j(ckD#G>2}Y z8|X)LecI!@gr4xbLFz39vSule$4h{$b^)ne0;Hk^Sa9XIK3~7nRREMbk`nIvyWvrdX7>@m2>Udii)GM%avt4S)qtIB6@fmTh?hWk-fcC z=^bT#AkCP-nu*k*SO)%Ax@5SORh%R`)-$$h90M=IDc!1OWWY9s=m~%TJQ&AmHBL3Kl%QthHFntuw>cH(a<&I- zxB96zh;=zFr-+6P)mGZq+T6ScgZ2Q}=}VD88Ei)>n4k@Kn>s*2sUFLQEhjh!GytJe z3?c{I5YNJGJ*S0tVOF&4Mm)Y`?P4_T+jda6>XmO(krND4=WcSv{?mhc9?=nYgS>NgND^{9UuR6aly=_dXxq)Xnb1Ler zT@n()yb!R9P+a$}^?T3x&!Q^WZg^V*eKg(?k3KI)I!wC?58zL>Gwa5xQ0QTEXI=|4 x%S=4(EMlRU7f0C(WraRbl { - const ids = { - trending: trending.map((a) => String(a.id)), - popular: popular.map((a) => String(a.id)), - top: top.map((a) => String(a.id)), - seasonal: seasonal.map((a) => String(a.id)), + // Create a function to sort media by id + const sortMediaById = (mediaArray: Anime[] | Manga[], ids: string[]) => { + return ids.map((id) => (mediaArray as any[]).find((media: Anime | Manga) => String(media.id) === id)); }; - const trend = (await db - .query( - ` - SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} - WHERE id IN (${ids.trending.map((id) => `'${id}'`).join(", ")}) - ORDER BY title->>'english' ASC - `, - ) - .all()) as Anime[] | Manga[]; - - const pop = (await db - .query( - ` - SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} - WHERE id IN (${ids.popular.map((id) => `'${id}'`).join(", ")}) - ORDER BY title->>'english' ASC - `, - ) - .all()) as Anime[] | Manga[]; - - const t = (await db - .query( - ` - SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} - WHERE id IN (${ids.top.map((id) => `'${id}'`).join(", ")}) - ORDER BY title->>'english' ASC - `, - ) - .all()) as Anime[] | Manga[]; - - const season = (await db - .query( - ` - SELECT * FROM ${trending[0].type === Type.ANIME ? "anime" : "manga"} - WHERE id IN (${ids.seasonal.map((id) => `'${id}'`).join(", ")}) - ORDER BY title->>'english' ASC - `, - ) - .all()) as Anime[] | Manga[]; - - trend.map((media) => { - if (media.type === Type.ANIME) { - Object.assign(media, { - title: JSON.parse((media as any).title), - season: (media as any).season.replace(/"/g, ""), - mappings: JSON.parse((media as any).mappings), - synonyms: JSON.parse((media as any).synonyms), - rating: JSON.parse((media as any).rating), - popularity: JSON.parse((media as any).popularity), - relations: JSON.parse((media as any).relations), - genres: JSON.parse((media as any).genres), - tags: JSON.parse((media as any).tags), - episodes: JSON.parse((media as any).episodes), - artwork: JSON.parse((media as any).artwork), - characters: JSON.parse((media as any).characters), - }); - } else { - Object.assign(media, { - title: JSON.parse((media as any).title), - mappings: JSON.parse((media as any).mappings), - synonyms: JSON.parse((media as any).synonyms), - rating: JSON.parse((media as any).rating), - popularity: JSON.parse((media as any).popularity), - relations: JSON.parse((media as any).relations), - genres: JSON.parse((media as any).genres), - tags: JSON.parse((media as any).tags), - chapters: JSON.parse((media as any).chapters), - artwork: JSON.parse((media as any).artwork), - characters: JSON.parse((media as any).characters), - }); - } - - media.characters = []; - }); - pop.map((media) => { - if (media.type === Type.ANIME) { - Object.assign(media, { - title: JSON.parse((media as any).title), - mappings: JSON.parse((media as any).mappings), - synonyms: JSON.parse((media as any).synonyms), - rating: JSON.parse((media as any).rating), - popularity: JSON.parse((media as any).popularity), - relations: JSON.parse((media as any).relations), - genres: JSON.parse((media as any).genres), - tags: JSON.parse((media as any).tags), - episodes: JSON.parse((media as any).episodes), - artwork: JSON.parse((media as any).artwork), - characters: JSON.parse((media as any).characters), - }); - } else { - Object.assign(media, { - title: JSON.parse((media as any).title), - mappings: JSON.parse((media as any).mappings), - synonyms: JSON.parse((media as any).synonyms), - rating: JSON.parse((media as any).rating), - popularity: JSON.parse((media as any).popularity), - relations: JSON.parse((media as any).relations), - genres: JSON.parse((media as any).genres), - tags: JSON.parse((media as any).tags), - chapters: JSON.parse((media as any).chapters), - artwork: JSON.parse((media as any).artwork), - characters: JSON.parse((media as any).characters), - }); - } + // Fetch all media based on their types + const fetchMediaByType = async (type: Type, ids: string[]) => { + return (await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} WHERE id IN (${ids.map((id) => `'${id}'`).join(", ")}) ORDER BY title->>'english' ASC`)).all() as Anime[] | Manga[]; + }; - media.characters = []; - }); - t.map((media) => { - if (media.type === Type.ANIME) { - Object.assign(media, { - title: JSON.parse((media as any).title), - mappings: JSON.parse((media as any).mappings), - synonyms: JSON.parse((media as any).synonyms), - rating: JSON.parse((media as any).rating), - popularity: JSON.parse((media as any).popularity), - relations: JSON.parse((media as any).relations), - genres: JSON.parse((media as any).genres), - tags: JSON.parse((media as any).tags), - episodes: JSON.parse((media as any).episodes), - artwork: JSON.parse((media as any).artwork), - characters: JSON.parse((media as any).characters), - }); - } else { - Object.assign(media, { - title: JSON.parse((media as any).title), - mappings: JSON.parse((media as any).mappings), - synonyms: JSON.parse((media as any).synonyms), - rating: JSON.parse((media as any).rating), - popularity: JSON.parse((media as any).popularity), - relations: JSON.parse((media as any).relations), - genres: JSON.parse((media as any).genres), - tags: JSON.parse((media as any).tags), - chapters: JSON.parse((media as any).chapters), - artwork: JSON.parse((media as any).artwork), - characters: JSON.parse((media as any).characters), - }); - } + // Fetch media for each category + const [trend, pop, t, season] = await Promise.all([ + fetchMediaByType( + trending[0].type, + trending.map((a) => String(a.id)), + ), + fetchMediaByType( + popular[0].type, + popular.map((a) => String(a.id)), + ), + fetchMediaByType( + top[0].type, + top.map((a) => String(a.id)), + ), + fetchMediaByType( + seasonal[0].type, + seasonal.map((a) => String(a.id)), + ), + ]); - media.characters = []; - }); - season.map((media) => { - if (media.type === Type.ANIME) { - Object.assign(media, { - title: JSON.parse((media as any).title), - mappings: JSON.parse((media as any).mappings), - synonyms: JSON.parse((media as any).synonyms), - rating: JSON.parse((media as any).rating), - popularity: JSON.parse((media as any).popularity), - relations: JSON.parse((media as any).relations), - genres: JSON.parse((media as any).genres), - tags: JSON.parse((media as any).tags), - episodes: JSON.parse((media as any).episodes), - artwork: JSON.parse((media as any).artwork), - characters: JSON.parse((media as any).characters), - }); - } else { - Object.assign(media, { - title: JSON.parse((media as any).title), - mappings: JSON.parse((media as any).mappings), - synonyms: JSON.parse((media as any).synonyms), - rating: JSON.parse((media as any).rating), - popularity: JSON.parse((media as any).popularity), - relations: JSON.parse((media as any).relations), - genres: JSON.parse((media as any).genres), - tags: JSON.parse((media as any).tags), - chapters: JSON.parse((media as any).chapters), - artwork: JSON.parse((media as any).artwork), - characters: JSON.parse((media as any).characters), - }); - } + // Sort media arrays based on passed-in values + const sortedTrending = sortMediaById( + trend, + trending.map((a) => String(a.id)), + ); + const sortedPopular = sortMediaById( + pop, + popular.map((a) => String(a.id)), + ); + const sortedTop = sortMediaById( + t, + top.map((a) => String(a.id)), + ); + const sortedSeasonal = sortMediaById( + season, + seasonal.map((a) => String(a.id)), + ); - media.characters = []; + // Reset characters array for each media + [sortedTrending, sortedPopular, sortedTop, sortedSeasonal].forEach((mediaArray) => { + mediaArray.forEach((media) => { + // Assign fields here + }); }); - return { trending: trend, popular: pop, top: t, seasonal: season }; + return { + trending: sortedTrending, + popular: sortedPopular, + top: sortedTop, + seasonal: sortedSeasonal, + }; }; diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index f3cad55..216cc63 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -31,7 +31,7 @@ async function before() { if (data[i].status === MediaStatus.NOT_YET_RELEASED) { continue; } - queues.mappingQueue.add({ id: data[i].id, type: data[i].type }); + queues.mappingQueue.add({ id: data[i].id, type: data[i].type, formats: [data[i].format] }); } }); diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend-recode/src/lib/impl/mappings.ts index 33284b5..05d2de0 100644 --- a/anify-backend-recode/src/lib/impl/mappings.ts +++ b/anify-backend-recode/src/lib/impl/mappings.ts @@ -3,71 +3,48 @@ import { get } from "../../database/impl/get"; import emitter, { Events } from ".."; import { Anime, AnimeInfo, Manga, MangaInfo, Result } from "../../types/types"; import { Format, MediaStatus, ProviderType, Season, Type } from "../../types/enums"; -import { ANIME_PROVIDERS, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, animeProviders, baseProviders, infoProviders, mangaProviders, metaProviders } from "../../mappings"; +import { ANIME_PROVIDERS, BASE_PROVIDERS, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, animeProviders, baseProviders, infoProviders, mangaProviders, metaProviders } from "../../mappings"; import { clean, slugify } from "../../helper/title"; import { findBestMatch2DArray, similarity } from "../../helper/stringSimilarity"; import { averageMetric, isString } from "../../helper"; import InformationProvider from "../../mappings/impl/information"; -import { deleteEntry } from "../../database/impl/delete"; -export const loadMapping = async (data: { id: string; type: Type }, aniData?: AnimeInfo | MangaInfo | null, retries = 0, media?: Anime | Manga): Promise => { - const MIN_MAPPINGS = 3; - const MAX_RETRIES = 2; - - if (retries > 0) { - console.log(colors.yellow("Remapping ") + colors.blue(data.id) + colors.yellow(" with retry ") + colors.blue(retries + "") + colors.yellow("...")); - // Delete entry if exists - try { - const existing = await get(data.id); - - if (existing) { - await deleteEntry(data.id); - } - } catch (e) { - console.error(e); - console.log(colors.red("Error while deleting from database.")); - } - } - - if (!aniData) { - try { - // First check if exists in database - const existing = await get(data.id); +export const loadMapping = async (data: { id: string; type: Type; formats: Format[] }): Promise => { + try { + // First check if exists in database + const existing = await get(data.id); - if (existing) { - // If it does, emit the event and return - await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, [existing]); - return [existing] as Anime[] | Manga[]; - } - } catch (e) { - console.error(e); - console.log(colors.red("Error while fetching from database.")); + if (existing) { + // If it does, emit the event and return + await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, [existing]); + return [existing] as Anime[] | Manga[]; } + } catch (e) { + console.error(e); + console.log(colors.red("Error while fetching from database.")); } console.log(colors.gray("Loading mapping for ") + colors.blue(data.id) + colors.gray("...")); // Map only one media - if (!aniData) { - // TODO: If manga, use base provider for manga. Otherwise, use one for anime. - aniData = await baseProviders.anilist.getMedia(data.id); - } + //const baseData = await baseProviders.anilist.getMedia(data.id); + const baseData = await BASE_PROVIDERS.map((provider) => { + if (provider.type === data.type && provider.formats?.includes(data.formats[0])) { + return provider.getMedia(data.id); + } + })[0]; - if (!aniData) { + if (!baseData) { await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, []); return []; } - if ((aniData as any).isAdult) { - console.log(colors.red("Media is adult. Skipping...")); - return []; - } - if (aniData.status === MediaStatus.NOT_YET_RELEASED) { + if (baseData.status === MediaStatus.NOT_YET_RELEASED) { console.log(colors.red("Media is not yet released. Skipping...")); return []; } - const result = await map((aniData as any)?.type, [aniData?.format!], aniData, media); + const result = await map(baseData.type, [baseData.format], baseData); // Only return if the ID matches the one we're looking for // If it isn't, we don't want to return. @@ -76,11 +53,6 @@ export const loadMapping = async (data: { id: string; type: Type }, aniData?: An console.log(colors.gray("Found mapping for ") + colors.blue(data.id) + colors.gray(".") + colors.gray(" Saving...")); await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, [result[i]]); - // Only return if anime or manga mappings are greater than MIN_MAPPINGS. - const mappings = result[i].mappings.filter((item) => item.providerType === ProviderType.ANIME || item.providerType === ProviderType.MANGA); - - if (mappings.length < MIN_MAPPINGS && retries < MAX_RETRIES) return loadMapping(data, aniData, retries + 1, result[i]); - return [result[i]] as Anime[] | Manga[]; } } @@ -90,10 +62,10 @@ export const loadMapping = async (data: { id: string; type: Type }, aniData?: An }; // Map and insert a mapping into the database -export const insertMapping = async (data: { id: string; type: Type }, aniData: AnimeInfo | MangaInfo | undefined) => { - if ((aniData as any).isAdult) return []; +export const insertMapping = async (data: { id: string; type: Type }, baseData: AnimeInfo | MangaInfo | undefined) => { + if (!baseData || (baseData as any).isAdult) return []; - const result = await map((aniData as any)?.type, [aniData?.format!], aniData); + const result = await map(baseData.type, [baseData.format], baseData); // Only return if the ID matches the one we're looking for // If it isn't, we don't want to return. @@ -110,37 +82,22 @@ export const insertMapping = async (data: { id: string; type: Type }, aniData: A }; // Map a media to AniList -export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | MangaInfo | undefined, media?: Anime | Manga): Promise => { +export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | MangaInfo | undefined): Promise => { const providers = type === Type.ANIME ? ANIME_PROVIDERS : MANGA_PROVIDERS; providers.push(...(META_PROVIDERS as any)); - if (media) { - aniData?.synonyms?.push(...media.synonyms); - aniData?.synonyms?.push(...(media.title.english ? [media.title.english] : [])); - aniData?.synonyms?.push(...(media.title.native ? [media.title.native] : [])); - aniData?.synonyms?.push(...(media.title.romaji ? [media.title.romaji] : [])); - - if (aniData) { - aniData.title.english = media.title.english; - aniData.title.native = media.title.native; - aniData.title.romaji = media.title.romaji; - - aniData.format = media.format; - } - } - // Filter out providers that don't contain the format - const suitableProviders = providers - .filter((provider) => { + const suitableProviders = (providers as any[]) + .filter((provider: any) => { if (formats && provider.formats) { return formats.some((format) => provider.formats.includes(format)); } return true; }) - .reduce((acc: any[], currentProvider) => { + .reduce((acc: any[], currentProvider: any) => { const existingProvider = acc.find((provider: any) => provider.id === currentProvider.id); if (!existingProvider) { - acc.push(currentProvider); + acc.push(currentProvider as any); } return acc; }, []); diff --git a/anify-backend-recode/src/mappings/impl/base/anilist.ts b/anify-backend-recode/src/mappings/impl/base/anilist.ts index 6b45f5c..8c8de43 100644 --- a/anify-backend-recode/src/mappings/impl/base/anilist.ts +++ b/anify-backend-recode/src/mappings/impl/base/anilist.ts @@ -6,6 +6,9 @@ export default class AniListBase extends BaseProvider { override id = "anilist"; override url = "https://anilist.co"; + override type: Type = Type.ANIME; + override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; + private api = "https://graphql.anilist.co"; override async search(query: string, type: Type, formats: Format[], page: number, perPage: number): Promise { diff --git a/anify-backend-recode/src/mappings/impl/base/index.ts b/anify-backend-recode/src/mappings/impl/base/index.ts index cb52c0f..b03ca21 100644 --- a/anify-backend-recode/src/mappings/impl/base/index.ts +++ b/anify-backend-recode/src/mappings/impl/base/index.ts @@ -1,11 +1,14 @@ import Http from "../../../helper/request"; import { Format, Genres, ProviderType, Season, Type } from "../../../types/enums"; -import { Anime, AnimeInfo, Manga, MangaInfo } from "../../../types/types"; +import { Anime, AnimeInfo, MangaInfo } from "../../../types/types"; export default abstract class BaseProvider { abstract id: string; abstract url: string; + abstract type: Type; + abstract formats: Format[]; + public providerType: ProviderType = ProviderType.BASE; public customProxy: string | undefined; diff --git a/anify-backend-recode/src/worker/impl/mappings.ts b/anify-backend-recode/src/worker/impl/mappings.ts index b956567..e2edf8c 100644 --- a/anify-backend-recode/src/worker/impl/mappings.ts +++ b/anify-backend-recode/src/worker/impl/mappings.ts @@ -1,9 +1,9 @@ import QueueExecutor from "../../lib/executor"; import { loadMapping } from "../../lib/impl/mappings"; import colors from "colors"; -import { Type } from "../../types/enums"; +import { Format, Type } from "../../types/enums"; -const executor = new QueueExecutor<{ id: string; type: Type }>("mapping-executor") +const executor = new QueueExecutor<{ id: string; type: Type; formats: Format[] }>("mapping-executor") .executor(async (data) => { const media = await loadMapping(data); return media; diff --git a/anify-backend-recode/src/worker/impl/search.ts b/anify-backend-recode/src/worker/impl/search.ts index dda72be..062fa3a 100644 --- a/anify-backend-recode/src/worker/impl/search.ts +++ b/anify-backend-recode/src/worker/impl/search.ts @@ -8,7 +8,7 @@ const executor = new QueueExecutor<{ query: string; type: Type; formats: Format[ const media = await loadSearch(data); return media; }) - .callback((id) => console.debug(colors.green(`Finished searching for media ${id.query} via the database/AniList.`))) - .error((err, id) => console.error(colors.red(`Error occurred while searching for media via the database/AniList ${id.query}`), err)) + .callback((id) => console.debug(colors.green(`Finished searching for media ${id.query}.`))) + .error((err, id) => console.error(colors.red(`Error occurred while searching for media ${id.query}`), err)) .interval(1000); export default executor; diff --git a/anify-backend/src/worker/search.ts b/anify-backend/src/worker/search.ts index 9fed9c0..95ab3ba 100644 --- a/anify-backend/src/worker/search.ts +++ b/anify-backend/src/worker/search.ts @@ -8,7 +8,7 @@ const executor = new QueueExecutor<{ query: string; type: Type; formats: Format[ const media = await loadSearch(data); return media; }) - .callback((id) => console.debug(colors.green(`Finished searching for media ${id.query} via the database/AniList.`))) - .error((err, id) => console.error(colors.red(`Error occurred while searching for media via the database/AniList ${id.query}`), err)) + .callback((id) => console.debug(colors.green(`Finished searching for media ${id.query}.`))) + .error((err, id) => console.error(colors.red(`Error occurred while searching for media ${id.query}`), err)) .interval(1000); export default executor; From d9427716cfa1590cab9f3c7bd845ec11903cdd6d Mon Sep 17 00:00:00 2001 From: Eltik Date: Thu, 7 Sep 2023 09:47:39 -0400 Subject: [PATCH 14/77] Use multiple base providers --- anify-backend-recode/db.sqlite | Bin 233472 -> 233472 bytes anify-backend-recode/src/lib/impl/mappings.ts | 26 +- anify-backend-recode/src/lib/impl/search.ts | 10 +- .../src/mappings/impl/base/comick.ts | 287 ++++++++++++++++++ .../src/mappings/impl/information/comick.ts | 7 +- .../src/mappings/impl/information/mangadex.ts | 92 +++--- anify-backend-recode/src/mappings/index.ts | 3 +- 7 files changed, 363 insertions(+), 62 deletions(-) create mode 100644 anify-backend-recode/src/mappings/impl/base/comick.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 55d6d24dff8f8630454b1f7d2cd35e840adce6e6..6e31052a8e710267b260401cb37c8527c0c9c626 100644 GIT binary patch delta 23549 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 N=LS>=xeJo*{{wafsW|`u delta 15746 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 COObQ{ diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend-recode/src/lib/impl/mappings.ts index 05d2de0..fdab330 100644 --- a/anify-backend-recode/src/lib/impl/mappings.ts +++ b/anify-backend-recode/src/lib/impl/mappings.ts @@ -31,8 +31,10 @@ export const loadMapping = async (data: { id: string; type: Type; formats: Forma const baseData = await BASE_PROVIDERS.map((provider) => { if (provider.type === data.type && provider.formats?.includes(data.formats[0])) { return provider.getMedia(data.id); + } else { + return null; } - })[0]; + }).filter((x) => x !== null)[0]; if (!baseData) { await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, []); @@ -82,7 +84,7 @@ export const insertMapping = async (data: { id: string; type: Type }, baseData: }; // Map a media to AniList -export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | MangaInfo | undefined): Promise => { +export const map = async (type: Type, formats: Format[], baseData: AnimeInfo | MangaInfo | undefined): Promise => { const providers = type === Type.ANIME ? ANIME_PROVIDERS : MANGA_PROVIDERS; providers.push(...(META_PROVIDERS as any)); @@ -104,7 +106,7 @@ export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | Ma // Search for the media on each provider const promises = suitableProviders.map((provider: any) => { - const search = [provider.search(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native, aniData?.format, (aniData as any)?.year)]; + const search = [provider.search(baseData?.title.english ?? baseData?.title.romaji ?? baseData?.title.native, baseData?.format, baseData?.year)]; return Promise.all(search) .then((results) => { return results.find((r) => r?.length !== 0) || []; @@ -123,7 +125,7 @@ export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | Ma // Loop through each provider and find the best match for (let i = 0; i < resultsArray.length; i++) { const providerData = resultsArray[i]; - const title: string = (aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native)!; + const title: string = (baseData?.title.english ?? baseData?.title.romaji ?? baseData?.title.native)!; const providerTitles = providerData.map((m: Result) => { const titles = [m.title, ...(m.altTitles ?? [])]; @@ -136,7 +138,7 @@ export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | Ma continue; } - const titles = [aniData?.title.english, aniData?.title.romaji, aniData?.title.native].filter(isString); + const titles = [baseData?.title.english, baseData?.title.romaji, baseData?.title.native].filter(isString); const cleanedTitles = titles.map((x) => clean(x?.toLowerCase().trim() ?? "")); const bestMatchIndex = findBestMatch2DArray(cleanedTitles, providerTitles); @@ -148,11 +150,11 @@ export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | Ma const best: Result = providerData[bestMatchIndex.bestMatchIndex]; // Add checks - if (best.format != Format.UNKNOWN && aniData?.format && aniData?.format != Format.UNKNOWN && best.format != aniData?.format) continue; - if (best.year != 0 && aniData?.year && aniData?.year != 0 && best.year != aniData?.year) continue; + if (best.format != Format.UNKNOWN && baseData?.format && baseData?.format != Format.UNKNOWN && best.format != baseData?.format) continue; + if (best.year != 0 && baseData?.year && baseData?.year != 0 && best.year != baseData?.year) continue; - const altTitles: string[] = Object.values(aniData?.title ?? {}) - .concat(aniData?.synonyms ?? []) + const altTitles: string[] = Object.values(baseData?.title ?? {}) + .concat(baseData?.synonyms ?? []) .filter(isString); const sim = similarity(title, best.title, altTitles); @@ -161,8 +163,8 @@ export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | Ma if (mappings.filter((m) => m.data.id === best.id).length > 0) continue; mappings.push({ - id: aniData?.id ?? "", - slug: slugify(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native ?? ""), + id: baseData?.id ?? "", + slug: slugify(baseData?.title.english ?? baseData?.title.romaji ?? baseData?.title.native ?? ""), data: best, similarity: sim.value, }); @@ -171,7 +173,7 @@ export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | Ma // Create the media object const result = await createMedia(mappings, type); - console.log(colors.yellow("Finished fetching from providers.") + colors.blue(" - ") + colors.yellow(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native!)); + console.log(colors.yellow("Finished fetching from providers.") + colors.blue(" - ") + colors.yellow(baseData?.title.english ?? baseData?.title.romaji ?? baseData?.title.native!)); return result; }; diff --git a/anify-backend-recode/src/lib/impl/search.ts b/anify-backend-recode/src/lib/impl/search.ts index 81f39af..7d6a391 100644 --- a/anify-backend-recode/src/lib/impl/search.ts +++ b/anify-backend-recode/src/lib/impl/search.ts @@ -1,6 +1,6 @@ import emitter, { Events } from ".."; import { search } from "../../database/impl/search"; -import { baseProviders } from "../../mappings"; +import { BASE_PROVIDERS, baseProviders } from "../../mappings"; import { Format, Type } from "../../types/enums"; export const loadSearch = async (data: { query: string; type: Type; formats: Format[] }) => { @@ -11,7 +11,13 @@ export const loadSearch = async (data: { query: string; type: Type; formats: For return existing; } - const result = await baseProviders.anilist.search(data.query, data.type, data.formats, 0, 10); + const result = await BASE_PROVIDERS.map((provider) => { + if (provider.type === data.type && provider.formats?.includes(data.formats[0])) { + return provider.search(data.query, data.type, data.formats, 0, 10); + } else { + return null; + } + }).filter((x) => x !== null)[0]; await emitter.emitAsync(Events.COMPLETED_SEARCH_LOAD, result); return result; diff --git a/anify-backend-recode/src/mappings/impl/base/comick.ts b/anify-backend-recode/src/mappings/impl/base/comick.ts new file mode 100644 index 0000000..6b7b692 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/base/comick.ts @@ -0,0 +1,287 @@ +import BaseProvider from "."; +import { Format, Genres, MediaStatus, Season, Type } from "../../../types/enums"; +import { AnimeInfo, MangaInfo } from "../../../types/types"; + +export default class ComicKBase extends BaseProvider { + override id = "comick"; + override url = "https://comick.app"; + + override type: Type = Type.MANGA; + override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; + + // Docs: https://upload.comick.app/docs/static/index.html + private api = "https://api.comick.fun"; + + override async search(query: string, type: Type, formats: Format[], page: number, perPage: number): Promise { + const data: SearchResult[] = await (await this.request(`${this.api}/v1.0/search?type=comic&q=${encodeURIComponent(query)}&limit=${perPage ?? 25}&page=${page && page > 0 ? page : 1}`, {}, true)).json(); + const genresReq: { id: number; name: string; slug: string; comic_count: number }[] = await (await this.request(`${this.api}/genre`, {}, true)).json(); + + const results: AnimeInfo[] | MangaInfo[] = []; + + for (let i = 0; i < data.length; i++) { + const result = data[i]; + + let cover: any = result.md_covers ? result.md_covers[0] : null; + if (cover && cover.b2key != undefined) { + cover = "https://meo.comick.pictures/" + cover.b2key; + } + + const genreList: string[] = result.genres + .flatMap((genre) => { + return genresReq.map((genre2) => { + if (genre2.id === genre) { + return genre2.name; + } + return ""; + }); + }) + .filter((genre) => genre !== ""); + + results.push({ + id: result.slug, + title: { + english: result.md_titles && result.md_titles.length > 0 ? result.md_titles[0].title : result.title ?? result.slug, + native: null, + romaji: result.title ?? result.slug, + }, + countryOfOrigin: null, + color: null, + synonyms: result.md_titles ? result.md_titles.map((title) => title.title) : [], + totalChapters: null, + trailer: null, + totalVolumes: null, + currentEpisode: null, + coverImage: cover, + duration: null, + format: formats[0], + bannerImage: null, + description: result.desc, + genres: genreList as Genres[], + type: type, + year: result.year ?? 0, + tags: [], + popularity: result.follow_count, + season: Season.UNKNOWN, + rating: null, + artwork: [], + status: result.status === 1 ? MediaStatus.RELEASING : result.status === 2 ? MediaStatus.FINISHED : result.status === 3 ? MediaStatus.CANCELLED : result.status === 4 ? MediaStatus.HIATUS : MediaStatus.NOT_YET_RELEASED, + characters: [], + relations: [], + }); + } + + return results; + } + + override async searchAdvanced(query: string, type: Type, formats: Format[], page: number, perPage: number, genres?: Genres[], genresExcluded?: Genres[], year?: number, tags?: string[], tagsExcluded?: string[]): Promise { + const data: SearchResult[] = await (await this.request(`${this.api}/v1.0/search?type=comic&q=${encodeURIComponent(query)}&limit=${perPage ?? 25}&page=${page ?? 1}${Array.isArray(genres) ? `&genres=${genres.map((genre) => genre.toLowerCase()).join(",")}` : ""}${Array.isArray(genresExcluded) ? `&excludes=${genresExcluded.map((genre) => genre.toLowerCase()).join(",")}` : ""}${Array.isArray(tags) ? `&tags=${tags.map((tag) => tag.toLowerCase()).join(",")}` : ""}${year && year != 0 ? `&from=${year}&to=${year}` : ""}`, {}, true)).json(); + const genresReq: { id: number; name: string; slug: string; comic_count: number }[] = await (await this.request(`${this.api}/genre`, {}, true)).json(); + + const results: AnimeInfo[] | MangaInfo[] = []; + + for (let i = 0; i < data.length; i++) { + const result = data[i]; + + let cover: any = result.md_covers ? result.md_covers[0] : null; + if (cover && cover.b2key != undefined) { + cover = "https://meo.comick.pictures/" + cover.b2key; + } + + const genreList: string[] = result.genres + .flatMap((genre) => { + return genresReq.map((genre2) => { + if (genre2.id === genre) { + return genre2.name; + } + return ""; + }); + }) + .filter((genre) => genre !== ""); + + results.push({ + id: result.slug, + title: { + english: result.md_titles ? result.md_titles[0].title : result.title ?? result.slug, + native: null, + romaji: null, + }, + countryOfOrigin: null, + color: null, + synonyms: result.md_titles ? result.md_titles.map((title) => title.title) : [], + totalChapters: null, + trailer: null, + totalVolumes: null, + currentEpisode: null, + coverImage: cover, + duration: null, + format: formats[0], + bannerImage: null, + description: result.desc, + genres: genreList as Genres[], + type: type, + year: result.year ?? 0, + tags: [], + popularity: result.follow_count, + season: Season.UNKNOWN, + rating: null, + artwork: [], + status: result.status === 1 ? MediaStatus.RELEASING : result.status === 2 ? MediaStatus.FINISHED : result.status === 3 ? MediaStatus.CANCELLED : result.status === 4 ? MediaStatus.HIATUS : MediaStatus.NOT_YET_RELEASED, + characters: [], + relations: [], + }); + } + + return results; + } + + override async getMedia(id: string): Promise { + const req = await this.request(`${this.api}/comic/${id}`, {}, true); + + if (!req.ok) return undefined; + + const coverReq = await this.request(`${this.api}/comic/${id}/covers`, {}, true); + const covers: Covers = await coverReq.json(); + + const data: Comic = (await req.json()).comic; + + return { + id: String(data.slug), + type: Type.MANGA, + artwork: covers.md_covers.map((cover) => { + return { + img: "https://meo.comick.pictures/" + cover.b2key, + type: "poster", + providerId: this.id, + }; + }), + bannerImage: null, + characters: [], + color: null, + countryOfOrigin: data.country, + coverImage: + covers.md_covers.map((cover) => { + if (cover.is_primary) { + return `https://meo.comick.pictures/${cover.b2key}`; + } + })[0] ?? + data.md_covers.map((cover) => `https://meo.comick.pictures/${cover.b2key}`)[0] ?? + null, + currentEpisode: null, + description: data.parsed, + duration: null, + format: Format.MANGA, + genres: + (data.md_comic_md_genres.map((genre) => { + return genre.md_genres.name; + }) as Genres[]) ?? [], + popularity: Number(data.user_follow_count), + rating: Number(data.bayesian_rating), + relations: [], + season: Season.UNKNOWN, + status: data.status === 1 ? MediaStatus.FINISHED : MediaStatus.RELEASING, + synonyms: data.md_titles.map((title) => title.title), + tags: + data.mu_comics?.mu_comic_categories?.map((genre) => { + return genre.mu_categories.title; + }) ?? [], + title: { + english: data.md_titles.find((title) => title.lang === "en")?.title ?? data.title, + native: data.md_titles.find((title) => title.lang === "ja")?.title ?? null, + romaji: data.md_titles.find((title) => title.lang === "ja-ro")?.title ?? null, + }, + totalChapters: null, + totalVolumes: null, + trailer: null, + year: data.year, + }; + } +} + +interface SearchResult { + title: string; + id: number; + slug: string; + year: number; + rating: string; + rating_count: number; + follow_count: number; + user_follow_count: number; + content_rating: string; + created_at: string; + demographic: number; + md_titles: { title: string }[]; + md_covers: { vol: any; w: number; h: number; b2key: string }[]; + highlight: string; + desc: string; + genres: number[]; + status: number; +} + +interface Comic { + id: number; + hid: string; + title: string; + country: string; + status: number; + links: { al: string; ap: string; bw: string; kt: string; mu: string; amz: string; cdj: string; ebj: string; mal: string; raw: string }; + last_chapter: any; + chapter_count: number; + demographic: number; + hentai: boolean; + user_follow_count: number; + follow_rank: number; + comment_count: number; + follow_count: number; + desc: string; + parsed: string; + slug: string; + mismatch: any; + year: number; + bayesian_rating: any; + rating_count: number; + content_rating: string; + translation_completed: boolean; + relate_from: Array; + mies: any; + md_titles: { title: string; lang?: string }[]; + md_comic_md_genres: { md_genres: { name: string; type: string | null; slug: string; group: string } }[]; + mu_comics: { + licensed_in_english: any; + mu_comic_categories: { + mu_categories: { title: string; slug: string }; + positive_vote: number; + negative_vote: number; + }[]; + }; + md_covers: { vol: any; w: number; h: number; b2key: string }[]; + iso639_1: string; + lang_name: string; + lang_native: string; +} + +interface Covers { + id: number; + title: string; + slug: string; + links2: { + id: string; + slug: string; + enable: boolean; + }[]; + noindex: boolean; + country: string; + md_covers: { + id: number; + w: number; + h: number; + s: number; + gpurl: string; + md_comic_id: number; + url: string; + vol: string; + mdid: string | null; + b2key: string; + is_primary: boolean; + locale: string | boolean; + }[]; +} diff --git a/anify-backend-recode/src/mappings/impl/information/comick.ts b/anify-backend-recode/src/mappings/impl/information/comick.ts index 07e9e29..7f8b4aa 100644 --- a/anify-backend-recode/src/mappings/impl/information/comick.ts +++ b/anify-backend-recode/src/mappings/impl/information/comick.ts @@ -68,9 +68,10 @@ export default class ComicKInfo extends InformationProvider title.title), - tags: data.mu_comics.mu_comic_categories.map((genre) => { - return genre.mu_categories.title; - }), + tags: + data.mu_comics?.mu_comic_categories?.map((genre) => { + return genre.mu_categories.title; + }) ?? [], title: { english: data.md_titles.find((title) => title.lang === "en")?.title ?? data.title, native: data.md_titles.find((title) => title.lang === "ja")?.title ?? null, diff --git a/anify-backend-recode/src/mappings/impl/information/mangadex.ts b/anify-backend-recode/src/mappings/impl/information/mangadex.ts index da38592..2dfa8ea 100644 --- a/anify-backend-recode/src/mappings/impl/information/mangadex.ts +++ b/anify-backend-recode/src/mappings/impl/information/mangadex.ts @@ -23,50 +23,54 @@ export default class MangaDexInfo extends InformationProvider { - return Object.values(title)[0]; - }), - description: data.attributes.description.en ?? data.attributes.description.jp ?? data.attributes.description.jp_ro ?? data.attributes.description.ko ?? Object.values(data.attributes.description)[0], - countryOfOrigin: data.attributes.publicationDemographic ?? data.attributes.originalLanguage?.toUpperCase() ?? null, - characters: [], - genres: data.attributes.tags.filter((tag: any) => tag.attributes.group === "genre").map((tag: any) => tag.attributes.name.en), - year: data.attributes.year, - artwork: covers.data.map((cover: any) => { - const img = `${this.url}/covers/${mangadexId}/${cover.attributes.fileName}`; - const providerId = this.id; - const type = "poster"; - return { - img, - providerId, - type, - }; - }), - totalChapters: data.attributes.lastChapter ?? null, - totalVolumes: data.attributes.lastVolume ?? null, - status: data.attributes.status === "ongoing" ? MediaStatus.RELEASING : data.attributes.status === "completed" ? MediaStatus.FINISHED : null, - color: null, - currentEpisode: null, - duration: null, - popularity: null, - relations: [], - tags: data.attributes.tags.filter((tag: any) => tag.attributes.group === "theme").map((tag: any) => tag.attributes.name.en), - rating: null, - season: Season.UNKNOWN, - trailer: null, - format: Format.UNKNOWN, - coverImage: `${this.url}/covers/${mangadexId}/${data.relationships.find((element: any) => element.type === "cover_art").id}.jpg`, - bannerImage: null, - }; + return { + id: mangadexId, + type: media.type, + title: { + romaji: data.attributes.title.jp_ro ?? null, + english: data.attributes.title.en ?? null, + native: data.attributes.title.jp ?? null, + }, + synonyms: data.attributes.altTitles.map((title: { [key: string]: string }) => { + return Object.values(title)[0]; + }), + description: data.attributes.description.en ?? data.attributes.description.jp ?? data.attributes.description.jp_ro ?? data.attributes.description.ko ?? Object.values(data.attributes.description)[0], + countryOfOrigin: data.attributes.publicationDemographic ?? data.attributes.originalLanguage?.toUpperCase() ?? null, + characters: [], + genres: data.attributes.tags.filter((tag: any) => tag.attributes.group === "genre").map((tag: any) => tag.attributes.name.en), + year: data.attributes.year, + artwork: covers.data.map((cover: any) => { + const img = `${this.url}/covers/${mangadexId}/${cover.attributes.fileName}`; + const providerId = this.id; + const type = "poster"; + return { + img, + providerId, + type, + }; + }), + totalChapters: data.attributes.lastChapter ?? null, + totalVolumes: data.attributes.lastVolume ?? null, + status: data.attributes.status === "ongoing" ? MediaStatus.RELEASING : data.attributes.status === "completed" ? MediaStatus.FINISHED : null, + color: null, + currentEpisode: null, + duration: null, + popularity: null, + relations: [], + tags: data.attributes.tags.filter((tag: any) => tag.attributes.group === "theme").map((tag: any) => tag.attributes.name.en), + rating: null, + season: Season.UNKNOWN, + trailer: null, + format: Format.UNKNOWN, + coverImage: `${this.url}/covers/${mangadexId}/${data.relationships.find((element: any) => element.type === "cover_art").id}.jpg`, + bannerImage: null, + }; + } catch (e) { + return undefined; + } } } diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend-recode/src/mappings/index.ts index ec0c44a..a6952d0 100644 --- a/anify-backend-recode/src/mappings/index.ts +++ b/anify-backend-recode/src/mappings/index.ts @@ -6,6 +6,7 @@ import NineAnime from "./impl/anime/nineanime"; import Zoro from "./impl/anime/zoro"; import BaseProvider from "./impl/base"; import AniListBase from "./impl/base/anilist"; +import ComicKBase from "./impl/base/comick"; import InformationProvider from "./impl/information"; import AniList from "./impl/information/anilist"; import ComicKInfo from "./impl/information/comick"; @@ -62,7 +63,7 @@ const metaProviders: Record = META_PROVIDERS.reduce( {} as Record, ); -const BASE_PROVIDERS: BaseProvider[] = [new AniListBase()]; +const BASE_PROVIDERS: BaseProvider[] = [new AniListBase(), new ComicKBase()]; const baseProviders: Record = BASE_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; From 2efcdbbc47e694c4138d85beeda0206782c8a2c6 Mon Sep 17 00:00:00 2001 From: Eltik Date: Thu, 7 Sep 2023 13:34:18 -0400 Subject: [PATCH 15/77] Use MangaDex instead of ComicK --- anify-backend-recode/db.sqlite | Bin 233472 -> 233472 bytes anify-backend-recode/src/index.ts | 3 +- .../src/mappings/impl/base/comick.ts | 287 ------------------ .../src/mappings/impl/base/mangadex.ts | 267 ++++++++++++++++ .../src/mappings/impl/information/mangadex.ts | 4 +- anify-backend-recode/src/mappings/index.ts | 4 +- anify-backend-recode/src/server/impl/all.ts | 33 ++ 7 files changed, 306 insertions(+), 292 deletions(-) delete mode 100644 anify-backend-recode/src/mappings/impl/base/comick.ts create mode 100644 anify-backend-recode/src/mappings/impl/base/mangadex.ts create mode 100644 anify-backend-recode/src/server/impl/all.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 6e31052a8e710267b260401cb37c8527c0c9c626..2f43764eb8745cdcca902243b108853b65f55a22 100644 GIT binary patch delta 27134 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 delta 14211 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 { + //await db.run("DELETE from manga;"); await start(); }); diff --git a/anify-backend-recode/src/mappings/impl/base/comick.ts b/anify-backend-recode/src/mappings/impl/base/comick.ts deleted file mode 100644 index 6b7b692..0000000 --- a/anify-backend-recode/src/mappings/impl/base/comick.ts +++ /dev/null @@ -1,287 +0,0 @@ -import BaseProvider from "."; -import { Format, Genres, MediaStatus, Season, Type } from "../../../types/enums"; -import { AnimeInfo, MangaInfo } from "../../../types/types"; - -export default class ComicKBase extends BaseProvider { - override id = "comick"; - override url = "https://comick.app"; - - override type: Type = Type.MANGA; - override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; - - // Docs: https://upload.comick.app/docs/static/index.html - private api = "https://api.comick.fun"; - - override async search(query: string, type: Type, formats: Format[], page: number, perPage: number): Promise { - const data: SearchResult[] = await (await this.request(`${this.api}/v1.0/search?type=comic&q=${encodeURIComponent(query)}&limit=${perPage ?? 25}&page=${page && page > 0 ? page : 1}`, {}, true)).json(); - const genresReq: { id: number; name: string; slug: string; comic_count: number }[] = await (await this.request(`${this.api}/genre`, {}, true)).json(); - - const results: AnimeInfo[] | MangaInfo[] = []; - - for (let i = 0; i < data.length; i++) { - const result = data[i]; - - let cover: any = result.md_covers ? result.md_covers[0] : null; - if (cover && cover.b2key != undefined) { - cover = "https://meo.comick.pictures/" + cover.b2key; - } - - const genreList: string[] = result.genres - .flatMap((genre) => { - return genresReq.map((genre2) => { - if (genre2.id === genre) { - return genre2.name; - } - return ""; - }); - }) - .filter((genre) => genre !== ""); - - results.push({ - id: result.slug, - title: { - english: result.md_titles && result.md_titles.length > 0 ? result.md_titles[0].title : result.title ?? result.slug, - native: null, - romaji: result.title ?? result.slug, - }, - countryOfOrigin: null, - color: null, - synonyms: result.md_titles ? result.md_titles.map((title) => title.title) : [], - totalChapters: null, - trailer: null, - totalVolumes: null, - currentEpisode: null, - coverImage: cover, - duration: null, - format: formats[0], - bannerImage: null, - description: result.desc, - genres: genreList as Genres[], - type: type, - year: result.year ?? 0, - tags: [], - popularity: result.follow_count, - season: Season.UNKNOWN, - rating: null, - artwork: [], - status: result.status === 1 ? MediaStatus.RELEASING : result.status === 2 ? MediaStatus.FINISHED : result.status === 3 ? MediaStatus.CANCELLED : result.status === 4 ? MediaStatus.HIATUS : MediaStatus.NOT_YET_RELEASED, - characters: [], - relations: [], - }); - } - - return results; - } - - override async searchAdvanced(query: string, type: Type, formats: Format[], page: number, perPage: number, genres?: Genres[], genresExcluded?: Genres[], year?: number, tags?: string[], tagsExcluded?: string[]): Promise { - const data: SearchResult[] = await (await this.request(`${this.api}/v1.0/search?type=comic&q=${encodeURIComponent(query)}&limit=${perPage ?? 25}&page=${page ?? 1}${Array.isArray(genres) ? `&genres=${genres.map((genre) => genre.toLowerCase()).join(",")}` : ""}${Array.isArray(genresExcluded) ? `&excludes=${genresExcluded.map((genre) => genre.toLowerCase()).join(",")}` : ""}${Array.isArray(tags) ? `&tags=${tags.map((tag) => tag.toLowerCase()).join(",")}` : ""}${year && year != 0 ? `&from=${year}&to=${year}` : ""}`, {}, true)).json(); - const genresReq: { id: number; name: string; slug: string; comic_count: number }[] = await (await this.request(`${this.api}/genre`, {}, true)).json(); - - const results: AnimeInfo[] | MangaInfo[] = []; - - for (let i = 0; i < data.length; i++) { - const result = data[i]; - - let cover: any = result.md_covers ? result.md_covers[0] : null; - if (cover && cover.b2key != undefined) { - cover = "https://meo.comick.pictures/" + cover.b2key; - } - - const genreList: string[] = result.genres - .flatMap((genre) => { - return genresReq.map((genre2) => { - if (genre2.id === genre) { - return genre2.name; - } - return ""; - }); - }) - .filter((genre) => genre !== ""); - - results.push({ - id: result.slug, - title: { - english: result.md_titles ? result.md_titles[0].title : result.title ?? result.slug, - native: null, - romaji: null, - }, - countryOfOrigin: null, - color: null, - synonyms: result.md_titles ? result.md_titles.map((title) => title.title) : [], - totalChapters: null, - trailer: null, - totalVolumes: null, - currentEpisode: null, - coverImage: cover, - duration: null, - format: formats[0], - bannerImage: null, - description: result.desc, - genres: genreList as Genres[], - type: type, - year: result.year ?? 0, - tags: [], - popularity: result.follow_count, - season: Season.UNKNOWN, - rating: null, - artwork: [], - status: result.status === 1 ? MediaStatus.RELEASING : result.status === 2 ? MediaStatus.FINISHED : result.status === 3 ? MediaStatus.CANCELLED : result.status === 4 ? MediaStatus.HIATUS : MediaStatus.NOT_YET_RELEASED, - characters: [], - relations: [], - }); - } - - return results; - } - - override async getMedia(id: string): Promise { - const req = await this.request(`${this.api}/comic/${id}`, {}, true); - - if (!req.ok) return undefined; - - const coverReq = await this.request(`${this.api}/comic/${id}/covers`, {}, true); - const covers: Covers = await coverReq.json(); - - const data: Comic = (await req.json()).comic; - - return { - id: String(data.slug), - type: Type.MANGA, - artwork: covers.md_covers.map((cover) => { - return { - img: "https://meo.comick.pictures/" + cover.b2key, - type: "poster", - providerId: this.id, - }; - }), - bannerImage: null, - characters: [], - color: null, - countryOfOrigin: data.country, - coverImage: - covers.md_covers.map((cover) => { - if (cover.is_primary) { - return `https://meo.comick.pictures/${cover.b2key}`; - } - })[0] ?? - data.md_covers.map((cover) => `https://meo.comick.pictures/${cover.b2key}`)[0] ?? - null, - currentEpisode: null, - description: data.parsed, - duration: null, - format: Format.MANGA, - genres: - (data.md_comic_md_genres.map((genre) => { - return genre.md_genres.name; - }) as Genres[]) ?? [], - popularity: Number(data.user_follow_count), - rating: Number(data.bayesian_rating), - relations: [], - season: Season.UNKNOWN, - status: data.status === 1 ? MediaStatus.FINISHED : MediaStatus.RELEASING, - synonyms: data.md_titles.map((title) => title.title), - tags: - data.mu_comics?.mu_comic_categories?.map((genre) => { - return genre.mu_categories.title; - }) ?? [], - title: { - english: data.md_titles.find((title) => title.lang === "en")?.title ?? data.title, - native: data.md_titles.find((title) => title.lang === "ja")?.title ?? null, - romaji: data.md_titles.find((title) => title.lang === "ja-ro")?.title ?? null, - }, - totalChapters: null, - totalVolumes: null, - trailer: null, - year: data.year, - }; - } -} - -interface SearchResult { - title: string; - id: number; - slug: string; - year: number; - rating: string; - rating_count: number; - follow_count: number; - user_follow_count: number; - content_rating: string; - created_at: string; - demographic: number; - md_titles: { title: string }[]; - md_covers: { vol: any; w: number; h: number; b2key: string }[]; - highlight: string; - desc: string; - genres: number[]; - status: number; -} - -interface Comic { - id: number; - hid: string; - title: string; - country: string; - status: number; - links: { al: string; ap: string; bw: string; kt: string; mu: string; amz: string; cdj: string; ebj: string; mal: string; raw: string }; - last_chapter: any; - chapter_count: number; - demographic: number; - hentai: boolean; - user_follow_count: number; - follow_rank: number; - comment_count: number; - follow_count: number; - desc: string; - parsed: string; - slug: string; - mismatch: any; - year: number; - bayesian_rating: any; - rating_count: number; - content_rating: string; - translation_completed: boolean; - relate_from: Array; - mies: any; - md_titles: { title: string; lang?: string }[]; - md_comic_md_genres: { md_genres: { name: string; type: string | null; slug: string; group: string } }[]; - mu_comics: { - licensed_in_english: any; - mu_comic_categories: { - mu_categories: { title: string; slug: string }; - positive_vote: number; - negative_vote: number; - }[]; - }; - md_covers: { vol: any; w: number; h: number; b2key: string }[]; - iso639_1: string; - lang_name: string; - lang_native: string; -} - -interface Covers { - id: number; - title: string; - slug: string; - links2: { - id: string; - slug: string; - enable: boolean; - }[]; - noindex: boolean; - country: string; - md_covers: { - id: number; - w: number; - h: number; - s: number; - gpurl: string; - md_comic_id: number; - url: string; - vol: string; - mdid: string | null; - b2key: string; - is_primary: boolean; - locale: string | boolean; - }[]; -} diff --git a/anify-backend-recode/src/mappings/impl/base/mangadex.ts b/anify-backend-recode/src/mappings/impl/base/mangadex.ts new file mode 100644 index 0000000..e65e101 --- /dev/null +++ b/anify-backend-recode/src/mappings/impl/base/mangadex.ts @@ -0,0 +1,267 @@ +import BaseProvider from "."; +import { wait } from "../../../helper"; +import { Format, Formats, Genres, MediaStatus, Season, Type } from "../../../types/enums"; +import { AnimeInfo, MangaInfo } from "../../../types/types"; + +export default class ManagDexBase extends BaseProvider { + override id = "mangadex"; + override url = "https://mangadex.org"; + + override type: Type = Type.MANGA; + override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; + + private api = "https://api.mangadex.org"; + + override async search(query: string, type: Type, formats: Format[], page: number, perPage: number): Promise { + const results: AnimeInfo[] | MangaInfo[] = []; + + let mangaList: any[] = []; + + for (let page = 0; page <= 1; page += 1) { + const uri = new URL("/manga", this.api); + uri.searchParams.set("title", query); + uri.searchParams.set("limit", !perPage || perPage === 0 ? "25" : String(perPage).toString()); + uri.searchParams.set("offset", String((!perPage || perPage === 0 ? 25 : perPage) * page).toString()); + uri.searchParams.set("order[relevance]", "desc"); + uri.searchParams.append("contentRating[]", "safe"); + uri.searchParams.append("contentRating[]", "suggestive"); + uri.searchParams.append("contentRating[]", "erotica"); + uri.searchParams.append("contentRating[]", "pornographic"); + uri.searchParams.append("includes[]", "cover_art"); + + const data = await (await this.request(uri.href)).json(); + // API rate limit + await wait(250); + + mangaList = [...mangaList, ...data.data]; + } + + for (let i = 0; i < mangaList.length; i++) { + const manga = mangaList[i]; + const attributes = manga.attributes; + const relationships = manga.relationships; + + const altTitles: string[] = attributes.altTitles.map((title: { [key: string]: string }) => { + return Object.values(title)[0]; + }).concat(Object.values(attributes.title)); + + const id = manga.id; + let img = null; + relationships.map((element: { id: string; type: string; related: string; attributes: { [key: string]: string } }) => { + if (element.type === "cover_art") { + img = `${this.url}/covers/${id}/${element.id}.jpg.512.jpg`; + } + }); + + const formatString: string = manga.type.toUpperCase(); + const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + results.push({ + id, + title: { + english: attributes.title["en"] ?? null, + romaji: attributes.title["ja-ro"] ?? attributes.title["jp-ro"] ?? null, + native: attributes.title["jp"] ?? attributes.title["ja"] ?? attributes.title["ko"] ?? null, + }, + synonyms: altTitles, + coverImage: img, + format, + year: attributes.year, + artwork: [], + bannerImage: null, + characters: [], + color: null, + countryOfOrigin: attributes.publicationDemographic ?? attributes.originalLanguage?.toUpperCase() ?? null, + description: attributes.description.en ?? Object.values(attributes.description)[0], + currentEpisode: null, + duration: null, + genres: attributes.tags.filter((tag: any) => tag.attributes.group === "genre").map((tag: any) => tag.attributes.name.en), + totalChapters: attributes.lastChapter ?? null, + totalVolumes: attributes.lastVolume ?? null, + status: attributes.status === "ongoing" ? MediaStatus.RELEASING : attributes.status === "completed" ? MediaStatus.FINISHED : null, + tags: attributes.tags.filter((tag: any) => tag.attributes.group === "theme").map((tag: any) => tag.attributes.name.en), + popularity: null, + relations: [], + rating: null, + season: Season.UNKNOWN, + trailer: null, + type: Type.MANGA + }); + } + + return results; + } + + override async searchAdvanced(query: string, type: Type, formats: Format[], page: number, perPage: number, genres?: Genres[], genresExcluded?: Genres[], year?: number, tags?: string[], tagsExcluded?: string[]): Promise { + const results: AnimeInfo[] | MangaInfo[] = []; + + let mangaList: any[] = []; + + const genreList: { name: string, uid: string }[] = []; + const tagList: { name: string, uid: string }[] = []; + + if (Array.isArray(tags) && tags.length > 0 || Array.isArray(tagsExcluded) && tagsExcluded.length > 0) { + const data = await (await this.request(`${this.api}/manga/tag`, {}, true)).json(); + + for (const item of data) { + if (item.attributes?.group === "theme") { + genreList.push({ + name: item.attributes?.name?.en, + uid: item.id, + }) + } else if (item.attributes?.group === "tag") { + tagList.push({ + name: item.attributes?.name?.en, + uid: item.id, + }) + } + } + } + + for (let page = 0; page <= 1; page += 1) { + const uri = new URL("/manga", this.api); + uri.searchParams.set("title", query); + uri.searchParams.set("limit", !perPage || perPage === 0 ? "25" : String(perPage).toString()); + uri.searchParams.set("offset", String((!perPage || perPage === 0 ? 25 : perPage) * page).toString()); + uri.searchParams.set("order[relevance]", "desc"); + uri.searchParams.append("contentRating[]", "safe"); + uri.searchParams.append("contentRating[]", "suggestive"); + uri.searchParams.append("contentRating[]", "erotica"); + uri.searchParams.append("contentRating[]", "pornographic"); + uri.searchParams.append("includes[]", "cover_art"); + + if (year) uri.searchParams.set("year", String(year)); + if (genres && genres.length > 0) { + uri.searchParams.append("includedTags[]", genres.map((genre) => genreList.find((item) => item.name === genre)?.uid).filter((x) => x !== undefined).join(",")); + uri.searchParams.set("includedTagsMode", "AND"); + } + if (genresExcluded && genresExcluded.length > 0) { + uri.searchParams.append("excludedTags[]", genresExcluded.map((genre) => genreList.find((item) => item.name === genre)?.uid).filter((x) => x !== undefined).join(",")); + if (!uri.searchParams.get("includedTagsMode")) uri.searchParams.set("includedTagsMode", "AND"); + } + if (tags && tags.length > 0) { + uri.searchParams.append("includedTags[]", tags.map((tag) => tagList.find((item) => item.name === tag)?.uid).filter((x) => x !== undefined).join(",")); + if (!uri.searchParams.get("includedTagsMode")) uri.searchParams.set("includedTagsMode", "AND"); + } + if (tagsExcluded && tagsExcluded.length > 0) { + uri.searchParams.append("excludedTags[]", tagsExcluded.map((tag) => tagList.find((item) => item.name === tag)?.uid).filter((x) => x !== undefined).join(",")); + if (!uri.searchParams.get("includedTagsMode")) uri.searchParams.set("includedTagsMode", "AND"); + } + + const data = await (await this.request(uri.href)).json(); + // API rate limit + await wait(250); + + mangaList = [...mangaList, ...data.data]; + } + + for (let i = 0; i < mangaList.length; i++) { + const manga = mangaList[i]; + const attributes = manga.attributes; + const relationships = manga.relationships; + + const altTitles: string[] = attributes.altTitles.map((title: { [key: string]: string }) => { + return Object.values(title)[0]; + }).concat(Object.values(attributes.title)); + + const id = manga.id; + let img = null; + relationships.map((element: { id: string; type: string; related: string; attributes: { [key: string]: string } }) => { + if (element.type === "cover_art") { + img = `${this.url}/covers/${id}/${element.id}.jpg.512.jpg`; + } + }); + + const formatString: string = manga.type.toUpperCase(); + const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + results.push({ + id, + title: { + english: attributes.title["en"] ?? null, + romaji: attributes.title["ja-ro"] ?? attributes.title["jp-ro"] ?? null, + native: attributes.title["jp"] ?? attributes.title["ja"] ?? attributes.title["ko"] ?? null, + }, + synonyms: altTitles, + coverImage: img, + format, + year: attributes.year, + artwork: [], + bannerImage: null, + characters: [], + color: null, + countryOfOrigin: attributes.publicationDemographic ?? attributes.originalLanguage?.toUpperCase() ?? null, + description: attributes.description.en ?? Object.values(attributes.description)[0], + currentEpisode: null, + duration: null, + genres: attributes.tags.filter((tag: any) => tag.attributes.group === "genre").map((tag: any) => tag.attributes.name.en), + totalChapters: attributes.lastChapter ?? null, + totalVolumes: attributes.lastVolume ?? null, + status: attributes.status === "ongoing" ? MediaStatus.RELEASING : attributes.status === "completed" ? MediaStatus.FINISHED : null, + tags: attributes.tags.filter((tag: any) => tag.attributes.group === "theme").map((tag: any) => tag.attributes.name.en), + popularity: null, + relations: [], + rating: null, + season: Season.UNKNOWN, + trailer: null, + type: Type.MANGA + }); + } + return results; + } + + override async getMedia(id: string): Promise { + try { + const data = (await (await this.request(`${this.api}/manga/${id}`, {}, true)).json()).data; + const covers = await (await this.request(`${this.api}/cover?limit=100&manga[]=${id}`, {}, true)).json(); + + const formatString: string = data.type.toUpperCase(); + const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + return { + id: id, + type: Type.MANGA, + title: { + romaji: data.attributes.title["ja-ro"] ?? data.attributes.title["jp_ro"] ?? null, + english: data.attributes.title.en ?? null, + native: data.attributes.title.jp ?? data.attributes.title.ja ?? null, + }, + synonyms: data.attributes.altTitles.map((title: { [key: string]: string }) => { + return Object.values(title)[0]; + }), + description: data.attributes.description.en ?? data.attributes.description.jp ?? data.attributes.description.jp_ro ?? data.attributes.description.ko ?? Object.values(data.attributes.description)[0], + countryOfOrigin: data.attributes.publicationDemographic ?? data.attributes.originalLanguage?.toUpperCase() ?? null, + characters: [], + genres: data.attributes.tags.filter((tag: any) => tag.attributes.group === "genre").map((tag: any) => tag.attributes.name.en), + year: data.attributes.year, + artwork: covers.data.map((cover: any) => { + const img = `${this.url}/covers/${id}/${cover.attributes.fileName}`; + const providerId = this.id; + const type = "poster"; + return { + img, + providerId, + type, + }; + }), + totalChapters: data.attributes.lastChapter ?? null, + totalVolumes: data.attributes.lastVolume ?? null, + status: data.attributes.status === "ongoing" ? MediaStatus.RELEASING : data.attributes.status === "completed" ? MediaStatus.FINISHED : null, + color: null, + currentEpisode: null, + duration: null, + popularity: null, + relations: [], + tags: data.attributes.tags.filter((tag: any) => tag.attributes.group === "theme").map((tag: any) => tag.attributes.name.en), + rating: null, + season: Season.UNKNOWN, + trailer: null, + format, + coverImage: `${this.url}/covers/${id}/${data.relationships.find((element: any) => element.type === "cover_art").id}.jpg`, + bannerImage: null, + }; + } catch (e) { + return undefined; + } + } +} \ No newline at end of file diff --git a/anify-backend-recode/src/mappings/impl/information/mangadex.ts b/anify-backend-recode/src/mappings/impl/information/mangadex.ts index 2dfa8ea..f95361f 100644 --- a/anify-backend-recode/src/mappings/impl/information/mangadex.ts +++ b/anify-backend-recode/src/mappings/impl/information/mangadex.ts @@ -31,9 +31,9 @@ export default class MangaDexInfo extends InformationProvider { return Object.values(title)[0]; diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend-recode/src/mappings/index.ts index a6952d0..87aabb2 100644 --- a/anify-backend-recode/src/mappings/index.ts +++ b/anify-backend-recode/src/mappings/index.ts @@ -6,7 +6,7 @@ import NineAnime from "./impl/anime/nineanime"; import Zoro from "./impl/anime/zoro"; import BaseProvider from "./impl/base"; import AniListBase from "./impl/base/anilist"; -import ComicKBase from "./impl/base/comick"; +import ManagDexBase from "./impl/base/mangadex"; import InformationProvider from "./impl/information"; import AniList from "./impl/information/anilist"; import ComicKInfo from "./impl/information/comick"; @@ -63,7 +63,7 @@ const metaProviders: Record = META_PROVIDERS.reduce( {} as Record, ); -const BASE_PROVIDERS: BaseProvider[] = [new AniListBase(), new ComicKBase()]; +const BASE_PROVIDERS: BaseProvider[] = [new AniListBase(), new ManagDexBase()]; const baseProviders: Record = BASE_PROVIDERS.reduce( (acc, provider) => { acc[provider.id] = provider; diff --git a/anify-backend-recode/src/server/impl/all.ts b/anify-backend-recode/src/server/impl/all.ts new file mode 100644 index 0000000..a2ec76d --- /dev/null +++ b/anify-backend-recode/src/server/impl/all.ts @@ -0,0 +1,33 @@ +import queues from "../../worker"; +import { search } from "../../database/impl/search"; +import { Format, Type } from "../../types/enums"; +import { db } from "../../database"; + +export const handler = async (req: Request): Promise => { + try { + const anime = await db.query("SELECT * FROM anime;").all(); + const manga = await db.query("SELECT * FROM manga;").all(); + + return new Response(JSON.stringify({ + anime: anime, + manga: manga, + }), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + method: "GET", + path: "/all", + handler, +}; + +export default route; From 04394bf8b25f23c866ae9964a0a87a80b83d0513 Mon Sep 17 00:00:00 2001 From: Eltik Date: Thu, 7 Sep 2023 13:44:53 -0400 Subject: [PATCH 16/77] Fix MangaDex --- anify-backend-recode/db.sqlite | Bin 233472 -> 233472 bytes anify-backend-recode/src/lib/impl/search.ts | 2 +- .../src/mappings/impl/base/mangadex.ts | 88 +++++++++++------- .../src/mappings/impl/information/mangadex.ts | 6 +- anify-backend-recode/src/server/impl/all.ts | 17 ++-- 5 files changed, 70 insertions(+), 43 deletions(-) diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 2f43764eb8745cdcca902243b108853b65f55a22..3a695ab37a62bc303b793793e0499fba7a1ef297 100644 GIT binary patch delta 878 zcmXYw&ubGw6vwkO+ommTHwCrz2Xzu#YizdJB+X{)FH(OX3TpjTE&jmiW}010cH{2G zl9O%4f)`Pu4tT1fcv94gTTncz2NBeZC}>4{@GtP72VYtjKJfO<+xPvxnc0b%)`^+c ztE*e?1_FTrKm+7!8#2P($7eo7h2GiJ#@k}OmQ>T3BoA*v3V-2{~*CnB%zOocOv3CkezBqyZN>4Ek-2;|1>$QGuKuhy^ z872HX-w|!Sj|mQG0Wxkdi&$)&xL!HOEYBsQEN@!GGnna+G1GB9Qeo8TBL^%-M(s+B z=mpBpj-XCarxxQ^Mo{|&!*q#ZmSTjKN{&r+gSoX1q~tKyGxMfhc8RMSwq58WM{30t zyKLo2ky^5RpkSV7jw~0;AT?$?MM6Qx%8_x?Gax=oJ!(;T++>BE2_NN6r$8)PWI3`Q z7HndUT_6VQ0Y#g*W#>G!TNKYxE6*G-_J3`R>Woki*1*7$8;BtRuhgnQ8oG~`J=l|4 z(jzWoMK|2EWz^YLqiMroyX@#}6B&U$8-mf?C|O4nNlole1%FgecB~Q;T1NFpPNLUB z=#UNL=`0e9?6ARXg|pLe)6_wf4r*#zRR@+%w{c}^@d+OB9}l8#!B-a0$0j&7EGl&| uxDrX;T*AlN5)ej!6j1wJ(%dWIo^UUOwJI6t1LA-JU?2)4{TC&?bL~G^90qRy delta 9892 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 diff --git a/anify-backend-recode/src/lib/impl/search.ts b/anify-backend-recode/src/lib/impl/search.ts index 7d6a391..e782905 100644 --- a/anify-backend-recode/src/lib/impl/search.ts +++ b/anify-backend-recode/src/lib/impl/search.ts @@ -13,7 +13,7 @@ export const loadSearch = async (data: { query: string; type: Type; formats: For const result = await BASE_PROVIDERS.map((provider) => { if (provider.type === data.type && provider.formats?.includes(data.formats[0])) { - return provider.search(data.query, data.type, data.formats, 0, 10); + return provider.search(data.query, data.type, data.formats, 0, 1); } else { return null; } diff --git a/anify-backend-recode/src/mappings/impl/base/mangadex.ts b/anify-backend-recode/src/mappings/impl/base/mangadex.ts index e65e101..97f9fde 100644 --- a/anify-backend-recode/src/mappings/impl/base/mangadex.ts +++ b/anify-backend-recode/src/mappings/impl/base/mangadex.ts @@ -25,8 +25,6 @@ export default class ManagDexBase extends BaseProvider { uri.searchParams.set("order[relevance]", "desc"); uri.searchParams.append("contentRating[]", "safe"); uri.searchParams.append("contentRating[]", "suggestive"); - uri.searchParams.append("contentRating[]", "erotica"); - uri.searchParams.append("contentRating[]", "pornographic"); uri.searchParams.append("includes[]", "cover_art"); const data = await (await this.request(uri.href)).json(); @@ -41,9 +39,11 @@ export default class ManagDexBase extends BaseProvider { const attributes = manga.attributes; const relationships = manga.relationships; - const altTitles: string[] = attributes.altTitles.map((title: { [key: string]: string }) => { - return Object.values(title)[0]; - }).concat(Object.values(attributes.title)); + const altTitles: string[] = attributes.altTitles + .map((title: { [key: string]: string }) => { + return Object.values(title)[0]; + }) + .concat(Object.values(attributes.title)); const id = manga.id; let img = null; @@ -59,9 +59,9 @@ export default class ManagDexBase extends BaseProvider { results.push({ id, title: { - english: attributes.title["en"] ?? null, - romaji: attributes.title["ja-ro"] ?? attributes.title["jp-ro"] ?? null, - native: attributes.title["jp"] ?? attributes.title["ja"] ?? attributes.title["ko"] ?? null, + english: attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "en")?.en ?? null, + romaji: attributes.title["ja-ro"] ?? attributes.title["jp-ro"] ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja-ro")?.["ja-ro"] ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp-ro")?.["jp-ro"] ?? null, + native: attributes.title["jp"] ?? attributes.title["ja"] ?? attributes.title["ko"] ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp")?.jp ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja")?.ja ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ko")?.ko ?? null, }, synonyms: altTitles, coverImage: img, @@ -85,7 +85,7 @@ export default class ManagDexBase extends BaseProvider { rating: null, season: Season.UNKNOWN, trailer: null, - type: Type.MANGA + type: Type.MANGA, }); } @@ -97,10 +97,10 @@ export default class ManagDexBase extends BaseProvider { let mangaList: any[] = []; - const genreList: { name: string, uid: string }[] = []; - const tagList: { name: string, uid: string }[] = []; + const genreList: { name: string; uid: string }[] = []; + const tagList: { name: string; uid: string }[] = []; - if (Array.isArray(tags) && tags.length > 0 || Array.isArray(tagsExcluded) && tagsExcluded.length > 0) { + if ((Array.isArray(tags) && tags.length > 0) || (Array.isArray(tagsExcluded) && tagsExcluded.length > 0)) { const data = await (await this.request(`${this.api}/manga/tag`, {}, true)).json(); for (const item of data) { @@ -108,12 +108,12 @@ export default class ManagDexBase extends BaseProvider { genreList.push({ name: item.attributes?.name?.en, uid: item.id, - }) + }); } else if (item.attributes?.group === "tag") { tagList.push({ name: item.attributes?.name?.en, uid: item.id, - }) + }); } } } @@ -126,25 +126,47 @@ export default class ManagDexBase extends BaseProvider { uri.searchParams.set("order[relevance]", "desc"); uri.searchParams.append("contentRating[]", "safe"); uri.searchParams.append("contentRating[]", "suggestive"); - uri.searchParams.append("contentRating[]", "erotica"); - uri.searchParams.append("contentRating[]", "pornographic"); uri.searchParams.append("includes[]", "cover_art"); - + if (year) uri.searchParams.set("year", String(year)); if (genres && genres.length > 0) { - uri.searchParams.append("includedTags[]", genres.map((genre) => genreList.find((item) => item.name === genre)?.uid).filter((x) => x !== undefined).join(",")); + uri.searchParams.append( + "includedTags[]", + genres + .map((genre) => genreList.find((item) => item.name === genre)?.uid) + .filter((x) => x !== undefined) + .join(","), + ); uri.searchParams.set("includedTagsMode", "AND"); } if (genresExcluded && genresExcluded.length > 0) { - uri.searchParams.append("excludedTags[]", genresExcluded.map((genre) => genreList.find((item) => item.name === genre)?.uid).filter((x) => x !== undefined).join(",")); + uri.searchParams.append( + "excludedTags[]", + genresExcluded + .map((genre) => genreList.find((item) => item.name === genre)?.uid) + .filter((x) => x !== undefined) + .join(","), + ); if (!uri.searchParams.get("includedTagsMode")) uri.searchParams.set("includedTagsMode", "AND"); } if (tags && tags.length > 0) { - uri.searchParams.append("includedTags[]", tags.map((tag) => tagList.find((item) => item.name === tag)?.uid).filter((x) => x !== undefined).join(",")); + uri.searchParams.append( + "includedTags[]", + tags + .map((tag) => tagList.find((item) => item.name === tag)?.uid) + .filter((x) => x !== undefined) + .join(","), + ); if (!uri.searchParams.get("includedTagsMode")) uri.searchParams.set("includedTagsMode", "AND"); } if (tagsExcluded && tagsExcluded.length > 0) { - uri.searchParams.append("excludedTags[]", tagsExcluded.map((tag) => tagList.find((item) => item.name === tag)?.uid).filter((x) => x !== undefined).join(",")); + uri.searchParams.append( + "excludedTags[]", + tagsExcluded + .map((tag) => tagList.find((item) => item.name === tag)?.uid) + .filter((x) => x !== undefined) + .join(","), + ); if (!uri.searchParams.get("includedTagsMode")) uri.searchParams.set("includedTagsMode", "AND"); } @@ -160,9 +182,11 @@ export default class ManagDexBase extends BaseProvider { const attributes = manga.attributes; const relationships = manga.relationships; - const altTitles: string[] = attributes.altTitles.map((title: { [key: string]: string }) => { - return Object.values(title)[0]; - }).concat(Object.values(attributes.title)); + const altTitles: string[] = attributes.altTitles + .map((title: { [key: string]: string }) => { + return Object.values(title)[0]; + }) + .concat(Object.values(attributes.title)); const id = manga.id; let img = null; @@ -178,9 +202,9 @@ export default class ManagDexBase extends BaseProvider { results.push({ id, title: { - english: attributes.title["en"] ?? null, - romaji: attributes.title["ja-ro"] ?? attributes.title["jp-ro"] ?? null, - native: attributes.title["jp"] ?? attributes.title["ja"] ?? attributes.title["ko"] ?? null, + english: attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "en")?.en ?? null, + romaji: attributes.title["ja-ro"] ?? attributes.title["jp-ro"] ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja-ro")?.["ja-ro"] ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp-ro")?.["jp-ro"] ?? null, + native: attributes.title["jp"] ?? attributes.title["ja"] ?? attributes.title["ko"] ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp")?.jp ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja")?.ja ?? attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ko")?.ko ?? null, }, synonyms: altTitles, coverImage: img, @@ -204,7 +228,7 @@ export default class ManagDexBase extends BaseProvider { rating: null, season: Season.UNKNOWN, trailer: null, - type: Type.MANGA + type: Type.MANGA, }); } return results; @@ -222,9 +246,9 @@ export default class ManagDexBase extends BaseProvider { id: id, type: Type.MANGA, title: { - romaji: data.attributes.title["ja-ro"] ?? data.attributes.title["jp_ro"] ?? null, - english: data.attributes.title.en ?? null, - native: data.attributes.title.jp ?? data.attributes.title.ja ?? null, + english: data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "en")?.en ?? null, + romaji: data.attributes.title["ja-ro"] ?? data.attributes.title["jp-ro"] ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja-ro")?.["ja-ro"] ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp-ro")?.["jp-ro"] ?? null, + native: data.attributes.title["jp"] ?? data.attributes.title["ja"] ?? data.attributes.title["ko"] ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp")?.jp ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja")?.ja ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ko")?.ko ?? null, }, synonyms: data.attributes.altTitles.map((title: { [key: string]: string }) => { return Object.values(title)[0]; @@ -264,4 +288,4 @@ export default class ManagDexBase extends BaseProvider { return undefined; } } -} \ No newline at end of file +} diff --git a/anify-backend-recode/src/mappings/impl/information/mangadex.ts b/anify-backend-recode/src/mappings/impl/information/mangadex.ts index f95361f..0648c6e 100644 --- a/anify-backend-recode/src/mappings/impl/information/mangadex.ts +++ b/anify-backend-recode/src/mappings/impl/information/mangadex.ts @@ -31,9 +31,9 @@ export default class MangaDexInfo extends InformationProvider Object.keys(title)[0] === "en")?.en ?? null, + romaji: data.attributes.title["ja-ro"] ?? data.attributes.title["jp-ro"] ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja-ro")?.["ja-ro"] ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp-ro")?.["jp-ro"] ?? null, + native: data.attributes.title["jp"] ?? data.attributes.title["ja"] ?? data.attributes.title["ko"] ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp")?.jp ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja")?.ja ?? data.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ko")?.ko ?? null, }, synonyms: data.attributes.altTitles.map((title: { [key: string]: string }) => { return Object.values(title)[0]; diff --git a/anify-backend-recode/src/server/impl/all.ts b/anify-backend-recode/src/server/impl/all.ts index a2ec76d..7a7caa0 100644 --- a/anify-backend-recode/src/server/impl/all.ts +++ b/anify-backend-recode/src/server/impl/all.ts @@ -8,13 +8,16 @@ export const handler = async (req: Request): Promise => { const anime = await db.query("SELECT * FROM anime;").all(); const manga = await db.query("SELECT * FROM manga;").all(); - return new Response(JSON.stringify({ - anime: anime, - manga: manga, - }), { - status: 200, - headers: { "Content-Type": "application/json" }, - }); + return new Response( + JSON.stringify({ + anime: anime, + manga: manga, + }), + { + status: 200, + headers: { "Content-Type": "application/json" }, + }, + ); } catch (e) { console.error(e); return new Response(JSON.stringify({ error: "An error occurred." }), { From f3ee2f2f96fae95e89cc91f0951ab0843b76180c Mon Sep 17 00:00:00 2001 From: Eltik Date: Thu, 7 Sep 2023 13:53:36 -0400 Subject: [PATCH 17/77] Use AniList for novels --- anify-backend-recode/db.sqlite | Bin 233472 -> 233472 bytes anify-backend-recode/src/index.ts | 3 +- anify-backend-recode/src/lib/impl/mappings.ts | 2 +- anify-backend-recode/src/lib/impl/search.ts | 4 +- .../src/mappings/impl/base/anilist.ts | 3 +- .../src/mappings/impl/base/index.ts | 1 - .../src/mappings/impl/base/mangadex.ts | 1 - anify-backend-recode/src/server/impl/all.ts | 36 ------------------ 8 files changed, 5 insertions(+), 45 deletions(-) delete mode 100644 anify-backend-recode/src/server/impl/all.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 3a695ab37a62bc303b793793e0499fba7a1ef297..7ae2baf3d6e854dac07332d6fd41e712bc46ed1e 100644 GIT binary patch delta 28197 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 Rgkxo^EUwdMV`WQc{y#^h@4Wy3 delta 11172 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 BPFMf{ diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index f55ba0c..216cc63 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -3,14 +3,13 @@ dotenv.config(); import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; import { MediaStatus } from "./types/enums"; -import { db, init } from "./database"; +import { init } from "./database"; import emitter, { Events } from "./lib"; import { get } from "./database/impl/get"; import queues from "./worker"; import { start } from "./server"; before().then(async (_) => { - //await db.run("DELETE from manga;"); await start(); }); diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend-recode/src/lib/impl/mappings.ts index fdab330..f0020b8 100644 --- a/anify-backend-recode/src/lib/impl/mappings.ts +++ b/anify-backend-recode/src/lib/impl/mappings.ts @@ -29,7 +29,7 @@ export const loadMapping = async (data: { id: string; type: Type; formats: Forma // Map only one media //const baseData = await baseProviders.anilist.getMedia(data.id); const baseData = await BASE_PROVIDERS.map((provider) => { - if (provider.type === data.type && provider.formats?.includes(data.formats[0])) { + if (provider.formats?.includes(data.formats[0])) { return provider.getMedia(data.id); } else { return null; diff --git a/anify-backend-recode/src/lib/impl/search.ts b/anify-backend-recode/src/lib/impl/search.ts index e782905..26ba02f 100644 --- a/anify-backend-recode/src/lib/impl/search.ts +++ b/anify-backend-recode/src/lib/impl/search.ts @@ -12,8 +12,8 @@ export const loadSearch = async (data: { query: string; type: Type; formats: For } const result = await BASE_PROVIDERS.map((provider) => { - if (provider.type === data.type && provider.formats?.includes(data.formats[0])) { - return provider.search(data.query, data.type, data.formats, 0, 1); + if (provider.formats?.includes(data.formats[0])) { + return provider.search(data.query, data.type, data.formats, 0, 10); } else { return null; } diff --git a/anify-backend-recode/src/mappings/impl/base/anilist.ts b/anify-backend-recode/src/mappings/impl/base/anilist.ts index 8c8de43..fece257 100644 --- a/anify-backend-recode/src/mappings/impl/base/anilist.ts +++ b/anify-backend-recode/src/mappings/impl/base/anilist.ts @@ -6,8 +6,7 @@ export default class AniListBase extends BaseProvider { override id = "anilist"; override url = "https://anilist.co"; - override type: Type = Type.ANIME; - override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; + override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT, Format.NOVEL]; private api = "https://graphql.anilist.co"; diff --git a/anify-backend-recode/src/mappings/impl/base/index.ts b/anify-backend-recode/src/mappings/impl/base/index.ts index b03ca21..b6587c3 100644 --- a/anify-backend-recode/src/mappings/impl/base/index.ts +++ b/anify-backend-recode/src/mappings/impl/base/index.ts @@ -6,7 +6,6 @@ export default abstract class BaseProvider { abstract id: string; abstract url: string; - abstract type: Type; abstract formats: Format[]; public providerType: ProviderType = ProviderType.BASE; diff --git a/anify-backend-recode/src/mappings/impl/base/mangadex.ts b/anify-backend-recode/src/mappings/impl/base/mangadex.ts index 97f9fde..1dd52fd 100644 --- a/anify-backend-recode/src/mappings/impl/base/mangadex.ts +++ b/anify-backend-recode/src/mappings/impl/base/mangadex.ts @@ -7,7 +7,6 @@ export default class ManagDexBase extends BaseProvider { override id = "mangadex"; override url = "https://mangadex.org"; - override type: Type = Type.MANGA; override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; private api = "https://api.mangadex.org"; diff --git a/anify-backend-recode/src/server/impl/all.ts b/anify-backend-recode/src/server/impl/all.ts deleted file mode 100644 index 7a7caa0..0000000 --- a/anify-backend-recode/src/server/impl/all.ts +++ /dev/null @@ -1,36 +0,0 @@ -import queues from "../../worker"; -import { search } from "../../database/impl/search"; -import { Format, Type } from "../../types/enums"; -import { db } from "../../database"; - -export const handler = async (req: Request): Promise => { - try { - const anime = await db.query("SELECT * FROM anime;").all(); - const manga = await db.query("SELECT * FROM manga;").all(); - - return new Response( - JSON.stringify({ - anime: anime, - manga: manga, - }), - { - status: 200, - headers: { "Content-Type": "application/json" }, - }, - ); - } catch (e) { - console.error(e); - return new Response(JSON.stringify({ error: "An error occurred." }), { - status: 500, - headers: { "Content-Type": "application/json" }, - }); - } -}; - -const route = { - method: "GET", - path: "/all", - handler, -}; - -export default route; From 76c61bb75605e6ae07c0e28693ff593dea812678 Mon Sep 17 00:00:00 2001 From: Eltik Date: Thu, 7 Sep 2023 14:28:47 -0400 Subject: [PATCH 18/77] Episode fetching --- anify-backend-recode/db.sqlite | Bin 233472 -> 258048 bytes .../src/content/impl/episodes.ts | 90 ++++++++++++++++++ anify-backend-recode/src/content/index.ts | 5 + .../src/database/impl/create.ts | 2 +- .../src/database/impl/update.ts | 90 ++++++++++++++++++ anify-backend-recode/src/lib/impl/mappings.ts | 2 +- .../src/mappings/impl/anime/gogoanime.ts | 3 +- .../src/server/impl/episodes.ts | 38 ++++++++ 8 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 anify-backend-recode/src/content/impl/episodes.ts create mode 100644 anify-backend-recode/src/content/index.ts create mode 100644 anify-backend-recode/src/database/impl/update.ts create mode 100644 anify-backend-recode/src/server/impl/episodes.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 7ae2baf3d6e854dac07332d6fd41e712bc46ed1e..65f663e2add59311ce56dde5f7405ce8ba2896f9 100644 GIT binary patch delta 44848 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 JF|bsO``=t84qN~L delta 43136 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 => { + const media = await get(id); + if (!media) return []; + + const mappings = media.mappings; + const episodes: EpisodeData[] = []; + + const promises: Promise[] = mappings.map(async (mapping) => { + const provider = animeProviders[mapping.providerId]; + + if (!provider) return false; + + try { + const data = await provider.fetchEpisodes(String(mapping.id)).catch(() => []); + if (data && data.length === 0) return true; + + data?.map((episode) => { + if (!episode.updatedAt) episode.updatedAt = 0; + }); + + if (data) { + episodes.push({ + providerId: mapping.providerId, + episodes: data, + }); + } + return true; + } catch (e) { + return false; + } + }); + + await Promise.all(promises); + + let updatedAt = (media as Anime).episodes.latest.updatedAt; + let latestEpisode = (media as Anime).episodes.latest.latestEpisode; + let latestTitle = (media as Anime).episodes.latest.latestTitle; + + for (const provider of episodes) { + const latest = provider.episodes.reduce((prev, current) => (prev.number > current.number ? prev : current)); + if ((latest.number > latestEpisode || (latest.number === latestEpisode && latest.title !== latestTitle)) && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0 > updatedAt) { + updatedAt = latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0; + latestEpisode = Number(latest.number); + latestTitle = String(latest.title); + } + } + + const totalEpisodes = !(media as Anime).totalEpisodes || (media as Anime).totalEpisodes! < latestEpisode ? latestEpisode : (media as Anime).totalEpisodes; + + for (let j = 0; j < INFORMATION_PROVIDERS.length; j++) { + const provider = INFORMATION_PROVIDERS[j]; + // Fetch info baesd on the media + const info = await provider.info(media).catch((err) => { + console.log(colors.red(`Error while fetching info for ${media.id} from ${provider.id}`)); + console.error(err); + return null; + }); + + if (!info) { + continue; + } + + // Fill the media object with all necessary info + fillMediaInfo(media, info, provider); + } + + Object.assign(media, { + currentEpisode: (media as Anime).currentEpisode ?? latestEpisode, + totalEpisodes, + episodes: { + latest: { + latestEpisode, + latestTitle, + updatedAt, + }, + data: episodes, + }, + }); + + await update(media); + + return episodes; +}; diff --git a/anify-backend-recode/src/content/index.ts b/anify-backend-recode/src/content/index.ts new file mode 100644 index 0000000..1ae9e22 --- /dev/null +++ b/anify-backend-recode/src/content/index.ts @@ -0,0 +1,5 @@ +import { fetchEpisodes } from "./impl/episodes"; + +export default { + fetchEpisodes, +}; diff --git a/anify-backend-recode/src/database/impl/create.ts b/anify-backend-recode/src/database/impl/create.ts index 52380c2..368162a 100644 --- a/anify-backend-recode/src/database/impl/create.ts +++ b/anify-backend-recode/src/database/impl/create.ts @@ -5,7 +5,7 @@ import { Anime, Manga } from "../../types/types"; import { get } from "./get"; export const create = async (data: Anime | Manga) => { - if (await get(data.id)) return console.log("Yeah no it exists lol"); + if (await get(data.id)) return null; const query = ` INSERT INTO ${data.type === "ANIME" ? "anime" : "manga"} ( diff --git a/anify-backend-recode/src/database/impl/update.ts b/anify-backend-recode/src/database/impl/update.ts new file mode 100644 index 0000000..5d90611 --- /dev/null +++ b/anify-backend-recode/src/database/impl/update.ts @@ -0,0 +1,90 @@ +import { db } from ".."; +import { averageMetric } from "../../helper"; +import { Type } from "../../types/enums"; +import { Anime, Manga } from "../../types/types"; +import { get } from "./get"; + +export const update = async (data: Anime | Manga) => { + if (!(await get(data.id))) return null; + + const query = ` + UPDATE ${data.type === "ANIME" ? "anime" : "manga"} SET + slug = $slug, + coverImage = $coverImage, + bannerImage = $bannerImage, + ${data.type === Type.ANIME ? "trailer = $trailer," : ""} + status = $status, + ${data.type === Type.ANIME ? "season = $season," : ""} + title = $title, + ${data.type === Type.ANIME ? "currentEpisode = $currentEpisode," : ""} + mappings = $mappings, + synonyms = $synonyms, + countryOfOrigin = $countryOfOrigin, + description = $description, + ${data.type === Type.ANIME ? "duration = $duration," : ""} + color = $color, + year = $year, + rating = $rating, + popularity = $popularity, + type = $type, + format = $format, + relations = $relations, + ${data.type === Type.ANIME ? "totalEpisodes = $totalEpisodes," : ""} + ${data.type === Type.MANGA ? "totalVolumes = $totalVolumes," : ""} + genres = $genres, + tags = $tags, + ${data.type === Type.ANIME ? "episodes = $episodes," : ""} + ${data.type === Type.MANGA ? "chapters = $chapters," : ""} + averageRating = $averageRating, + averagePopularity = $averagePopularity, + artwork = $artwork, + characters = $characters + WHERE id = $id + `; + + const params = { + $id: data.id, + $slug: data.slug, + $coverImage: data.coverImage, + $bannerImage: data.bannerImage, + $status: data.status, + $title: JSON.stringify(data.title), + $mappings: JSON.stringify(data.mappings), + $synonyms: JSON.stringify(data.synonyms), + $countryOfOrigin: data.countryOfOrigin, + $description: data.description, + $color: data.color, + $year: data.year, + $rating: JSON.stringify(data.rating), + $popularity: JSON.stringify(data.popularity), + $type: data.type, + $format: data.format, + $relations: JSON.stringify(data.relations), + $genres: JSON.stringify(data.genres), + $tags: JSON.stringify(data.tags), + $averageRating: averageMetric(data.rating), + $averagePopularity: averageMetric(data.popularity), + $artwork: JSON.stringify(data.artwork), + $characters: JSON.stringify(data.characters), + }; + + if (data.type === Type.ANIME) { + Object.assign(params, { + $trailer: (data as Anime).trailer, + $season: JSON.stringify((data as Anime).season), + $currentEpisode: (data as Anime).currentEpisode, + $duration: (data as Anime).duration, + $totalEpisodes: (data as Anime).totalEpisodes, + $episodes: JSON.stringify((data as Anime).episodes), + }); + } else { + Object.assign(params, { + $totalChapters: (data as Manga).totalChapters, + $totalVolumes: (data as Manga).totalVolumes, + $chapters: JSON.stringify((data as Manga).chapters), + }); + } + + const update = await db.prepare(query).run(params); + return update; +}; diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend-recode/src/lib/impl/mappings.ts index f0020b8..cac1aea 100644 --- a/anify-backend-recode/src/lib/impl/mappings.ts +++ b/anify-backend-recode/src/lib/impl/mappings.ts @@ -325,7 +325,7 @@ export async function createMedia(mappings: MappedResult[], type: Type): Promise return results; } -function fillMediaInfo(media: T, info: U, provider: InformationProvider): T { +export function fillMediaInfo(media: T, info: U, provider: InformationProvider): T { try { // Fields that need to be cross loaded. For example, rating which contains Kitsu, AniList, and MAL fields. const crossLoadFields: (keyof AnimeInfo | MangaInfo)[] = ["popularity", "rating"]; diff --git a/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts b/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts index e429d0a..bf58e36 100644 --- a/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts +++ b/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts @@ -79,7 +79,8 @@ export default class GogoAnime extends AnimeProvider { hasDub: id.includes("-dub"), }); }); - return episodes; + + return episodes.reverse(); } override async fetchSources(id: string, subType = SubType.SUB, server: StreamingServers = StreamingServers.GogoCDN): Promise { diff --git a/anify-backend-recode/src/server/impl/episodes.ts b/anify-backend-recode/src/server/impl/episodes.ts new file mode 100644 index 0000000..8877b94 --- /dev/null +++ b/anify-backend-recode/src/server/impl/episodes.ts @@ -0,0 +1,38 @@ +import content from "../../content"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const id = paths[1] ?? url.searchParams.get("id") ?? null; + if (!id) { + return new Response(JSON.stringify({ error: "No ID provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const data = await content.fetchEpisodes(String(id)); + + return new Response(JSON.stringify(data), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + method: "GET", + path: "/episodes", + handler, +}; + +export default route; From 1377e1b1cc5cda7b0dec927031c048bd6863a1e2 Mon Sep 17 00:00:00 2001 From: Eltik Date: Thu, 7 Sep 2023 16:31:07 -0400 Subject: [PATCH 19/77] Added chapters --- anify-backend-recode/db.sqlite | Bin 258048 -> 258048 bytes .../src/content/impl/chapters.ts | 90 ++++++++++++++++++ anify-backend-recode/src/content/index.ts | 2 + .../src/database/impl/update.ts | 2 + anify-backend-recode/src/database/index.ts | 1 + anify-backend-recode/src/lib/impl/mappings.ts | 1 + .../src/server/impl/chapters.ts | 38 ++++++++ anify-backend-recode/src/types/types.ts | 1 + 8 files changed, 135 insertions(+) create mode 100644 anify-backend-recode/src/content/impl/chapters.ts create mode 100644 anify-backend-recode/src/server/impl/chapters.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 65f663e2add59311ce56dde5f7405ce8ba2896f9..bc1c2a8fb8148491b23114bf87b4c1f0c440106f 100644 GIT binary patch delta 7902 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 diff --git a/anify-backend-recode/src/content/impl/chapters.ts b/anify-backend-recode/src/content/impl/chapters.ts new file mode 100644 index 0000000..c64f763 --- /dev/null +++ b/anify-backend-recode/src/content/impl/chapters.ts @@ -0,0 +1,90 @@ +import { get } from "../../database/impl/get"; +import { update } from "../../database/impl/update"; +import { fillMediaInfo } from "../../lib/impl/mappings"; +import { INFORMATION_PROVIDERS, mangaProviders } from "../../mappings"; +import { ChapterData, Manga } from "../../types/types"; +import colors from "colors"; + +export const fetchChapters = async (id: string): Promise => { + const media = await get(id); + if (!media) return []; + + const mappings = media.mappings; + const chapters: ChapterData[] = []; + + const promises: Promise[] = mappings.map(async (mapping) => { + const provider = mangaProviders[mapping.providerId]; + + if (!provider) return false; + + try { + const data = await provider.fetchChapters(String(mapping.id)).catch(() => []); + if (data && data.length === 0) return true; + + data?.map((chapter) => { + if (!chapter.updatedAt) chapter.updatedAt = 0; + }); + + if (data) { + chapters.push({ + providerId: mapping.providerId, + chapters: data, + }); + } + return true; + } catch (e) { + return false; + } + }); + + await Promise.all(promises); + + let updatedAt = (media as Manga).chapters.latest.updatedAt; + let latestChapter = (media as Manga).chapters.latest.latestChapter; + let latestTitle = (media as Manga).chapters.latest.latestTitle; + + for (const provider of chapters) { + const latest = provider.chapters.reduce((prev, current) => (prev.number > current.number ? prev : current)); + if ((latest.number > latestChapter || (latest.number === latestChapter && latest.title !== latestTitle)) && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0 > updatedAt) { + updatedAt = latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0; + latestChapter = Number(latest.number); + latestTitle = String(latest.title); + } + } + + const totalEpisodes = !(media as Manga).totalChapters || (media as Manga).totalChapters! < latestChapter ? latestChapter : (media as Manga).totalChapters; + + for (let j = 0; j < INFORMATION_PROVIDERS.length; j++) { + const provider = INFORMATION_PROVIDERS[j]; + // Fetch info baesd on the media + const info = await provider.info(media).catch((err) => { + console.log(colors.red(`Error while fetching info for ${media.id} from ${provider.id}`)); + console.error(err); + return null; + }); + + if (!info) { + continue; + } + + // Fill the media object with all necessary info + fillMediaInfo(media, info, provider); + } + + Object.assign(media, { + currentChapter: (media as Manga).currentChapter ?? latestChapter, + totalEpisodes, + chapters: { + latest: { + latestChapter, + latestTitle, + updatedAt, + }, + data: chapters, + }, + }); + + await update(media); + + return chapters; +}; diff --git a/anify-backend-recode/src/content/index.ts b/anify-backend-recode/src/content/index.ts index 1ae9e22..04b170d 100644 --- a/anify-backend-recode/src/content/index.ts +++ b/anify-backend-recode/src/content/index.ts @@ -1,5 +1,7 @@ +import { fetchChapters } from "./impl/chapters"; import { fetchEpisodes } from "./impl/episodes"; export default { + fetchChapters, fetchEpisodes, }; diff --git a/anify-backend-recode/src/database/impl/update.ts b/anify-backend-recode/src/database/impl/update.ts index 5d90611..c527522 100644 --- a/anify-backend-recode/src/database/impl/update.ts +++ b/anify-backend-recode/src/database/impl/update.ts @@ -30,6 +30,8 @@ export const update = async (data: Anime | Manga) => { format = $format, relations = $relations, ${data.type === Type.ANIME ? "totalEpisodes = $totalEpisodes," : ""} + ${data.type === Type.MANGA ? "currentChapter = $currentChapter," : ""} + ${data.type === Type.MANGA ? "totalChapters = $totalChapters," : ""} ${data.type === Type.MANGA ? "totalVolumes = $totalVolumes," : ""} genres = $genres, tags = $tags, diff --git a/anify-backend-recode/src/database/index.ts b/anify-backend-recode/src/database/index.ts index f3e093b..f393403 100644 --- a/anify-backend-recode/src/database/index.ts +++ b/anify-backend-recode/src/database/index.ts @@ -57,6 +57,7 @@ export const init = async () => { type TEXT, format TEXT DEFAULT 'UNKNOWN', relations JSON DEFAULT '[]', + currentChapter INTEGER, totalChapters REAL, totalVolumes REAL, genres JSON DEFAULT '[]', diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend-recode/src/lib/impl/mappings.ts index cac1aea..b536935 100644 --- a/anify-backend-recode/src/lib/impl/mappings.ts +++ b/anify-backend-recode/src/lib/impl/mappings.ts @@ -281,6 +281,7 @@ export async function createMedia(mappings: MappedResult[], type: Type): Promise genres: [], format: Format.UNKNOWN, relations: [], + currentChapter: null, totalChapters: 0, totalVolumes: 0, chapters: { diff --git a/anify-backend-recode/src/server/impl/chapters.ts b/anify-backend-recode/src/server/impl/chapters.ts new file mode 100644 index 0000000..23fa9e9 --- /dev/null +++ b/anify-backend-recode/src/server/impl/chapters.ts @@ -0,0 +1,38 @@ +import content from "../../content"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const id = paths[1] ?? url.searchParams.get("id") ?? null; + if (!id) { + return new Response(JSON.stringify({ error: "No ID provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const data = await content.fetchChapters(String(id)); + + return new Response(JSON.stringify(data), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + method: "GET", + path: "/chapters", + handler, +}; + +export default route; diff --git a/anify-backend-recode/src/types/types.ts b/anify-backend-recode/src/types/types.ts index e57b285..81bc6c5 100644 --- a/anify-backend-recode/src/types/types.ts +++ b/anify-backend-recode/src/types/types.ts @@ -58,6 +58,7 @@ export type Manga = { synonyms: string[]; countryOfOrigin: string | null; description: string | null; + currentChapter: number | null; totalVolumes: number | null; color: string | null; year: number | null; From 9d5b8c86d4a8d2efa221475df4234f98d885bf6d Mon Sep 17 00:00:00 2001 From: Eltik Date: Fri, 8 Sep 2023 16:33:43 -0400 Subject: [PATCH 20/77] Skip times! --- anify-backend-recode/db.sqlite | Bin 258048 -> 258048 bytes .../src/content/impl/pages.ts | 19 + .../src/content/impl/sources.ts | 21 + anify-backend-recode/src/content/index.ts | 4 + .../impl/skipTimes/createSkipTimes.ts | 25 + .../database/impl/skipTimes/getSkipTimes.ts | 6 + .../impl/skipTimes/updateSkipTimes.ts | 22 + anify-backend-recode/src/index.ts | 1 + .../src/lib/impl/skipTimes.ts | 56 + anify-backend-recode/src/server/impl/pages.ts | 46 + .../src/server/impl/sources.ts | 62 + anify-backend-recode/src/types/types.ts | 17 + .../src/worker/impl/skipTimes.ts | 14 + anify-backend-recode/src/worker/index.ts | 2 + anify-backend/src/server/impl/stats.ts | 22 - anify-backend/src/server/index.ts | 2021 ++++++++++++++++- 16 files changed, 2290 insertions(+), 48 deletions(-) create mode 100644 anify-backend-recode/src/content/impl/pages.ts create mode 100644 anify-backend-recode/src/content/impl/sources.ts create mode 100644 anify-backend-recode/src/database/impl/skipTimes/createSkipTimes.ts create mode 100644 anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts create mode 100644 anify-backend-recode/src/database/impl/skipTimes/updateSkipTimes.ts create mode 100644 anify-backend-recode/src/lib/impl/skipTimes.ts create mode 100644 anify-backend-recode/src/server/impl/pages.ts create mode 100644 anify-backend-recode/src/server/impl/sources.ts create mode 100644 anify-backend-recode/src/worker/impl/skipTimes.ts delete mode 100644 anify-backend/src/server/impl/stats.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index bc1c2a8fb8148491b23114bf87b4c1f0c440106f..c71d4509f3b8d12311014ad93f397f6639cb04d7 100644 GIT binary patch delta 16455 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 N^Wgixce+p+`#;ios;mG2 delta 16093 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%0AX@ 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 diff --git a/anify-backend-recode/src/content/impl/pages.ts b/anify-backend-recode/src/content/impl/pages.ts new file mode 100644 index 0000000..66ab5a6 --- /dev/null +++ b/anify-backend-recode/src/content/impl/pages.ts @@ -0,0 +1,19 @@ +import { mangaProviders } from "../../mappings"; +import { StreamingServers, SubType } from "../../types/enums"; +import { Page, Source } from "../../types/types"; + +export const fetchPages = async (providerId: string, readId: string): Promise => { + const provider = mangaProviders[providerId]; + + if (!provider) return null; + + try { + const data = await provider.fetchPages(readId).catch(() => { + return null; + }); + if (!data) return null; + return data; + } catch (e) { + return null; + } +}; diff --git a/anify-backend-recode/src/content/impl/sources.ts b/anify-backend-recode/src/content/impl/sources.ts new file mode 100644 index 0000000..4a0df0c --- /dev/null +++ b/anify-backend-recode/src/content/impl/sources.ts @@ -0,0 +1,21 @@ +import { animeProviders } from "../../mappings"; +import { StreamingServers, SubType } from "../../types/enums"; +import { Source } from "../../types/types"; + +export const fetchSources = async (providerId: string, watchId: string, subType: SubType, server: StreamingServers): Promise => { + const provider = animeProviders[providerId]; + + if (!provider) return null; + + if (provider.subTypes && !provider.subTypes.includes(subType)) return null; + + try { + const data = await provider.fetchSources(watchId, subType, server).catch(() => { + return null; + }); + if (!data) return null; + return data; + } catch (e) { + return null; + } +}; diff --git a/anify-backend-recode/src/content/index.ts b/anify-backend-recode/src/content/index.ts index 04b170d..d8e5344 100644 --- a/anify-backend-recode/src/content/index.ts +++ b/anify-backend-recode/src/content/index.ts @@ -1,7 +1,11 @@ import { fetchChapters } from "./impl/chapters"; import { fetchEpisodes } from "./impl/episodes"; +import { fetchSources } from "./impl/sources"; +import { fetchPages } from "./impl/pages"; export default { fetchChapters, fetchEpisodes, + fetchSources, + fetchPages, }; diff --git a/anify-backend-recode/src/database/impl/skipTimes/createSkipTimes.ts b/anify-backend-recode/src/database/impl/skipTimes/createSkipTimes.ts new file mode 100644 index 0000000..95fa187 --- /dev/null +++ b/anify-backend-recode/src/database/impl/skipTimes/createSkipTimes.ts @@ -0,0 +1,25 @@ +import { db } from "../.."; +import { SkipTime } from "../../../types/types"; +import { getSkipTimes } from "./getSkipTimes"; + +export const createSkipTimes = async (data: SkipTime) => { + if (await getSkipTimes(data.id)) return null; + + const query = ` + INSERT INTO skipTimes ( + id, + episodes + ) VALUES ( + $id, + $episodes + ) + `; + + const params = { + $id: data.id, + $episodes: JSON.stringify(data.episodes), + }; + + const insert = await db.prepare(query).run(params); + return insert; +}; diff --git a/anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts b/anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts new file mode 100644 index 0000000..1f3dafe --- /dev/null +++ b/anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts @@ -0,0 +1,6 @@ +import { db } from "../.."; +import { SkipTime } from "../../../types/types"; + +export const getSkipTimes = async (id: string): Promise => { + return (await db.query(`SELECT * FROM skipTimes WHERE id = $id`).get({ $id: id })) as SkipTime | undefined; +}; diff --git a/anify-backend-recode/src/database/impl/skipTimes/updateSkipTimes.ts b/anify-backend-recode/src/database/impl/skipTimes/updateSkipTimes.ts new file mode 100644 index 0000000..67bd6b9 --- /dev/null +++ b/anify-backend-recode/src/database/impl/skipTimes/updateSkipTimes.ts @@ -0,0 +1,22 @@ +import { db } from "../.."; +import { SkipTime } from "../../../types/types"; +import { createSkipTimes } from "./createSkipTimes"; +import { getSkipTimes } from "./getSkipTimes"; + +export const updateSkipTimes = async (data: SkipTime) => { + if (!(await getSkipTimes(data.id))) return await createSkipTimes(data); + + const query = ` + UPDATE skipTimes SET + episodes = $episodes + WHERE id = $id + `; + + const params = { + $id: data.id, + $episodes: JSON.stringify(data.episodes), + }; + + const update = await db.prepare(query).run(params); + return update; +}; diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 216cc63..6a74499 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -38,4 +38,5 @@ async function before() { queues.mappingQueue.start(); queues.createEntry.start(); queues.searchQueue.start(); + queues.skipTimes.start(); } diff --git a/anify-backend-recode/src/lib/impl/skipTimes.ts b/anify-backend-recode/src/lib/impl/skipTimes.ts new file mode 100644 index 0000000..34e9202 --- /dev/null +++ b/anify-backend-recode/src/lib/impl/skipTimes.ts @@ -0,0 +1,56 @@ +import colors from "colors"; +import { Source, Time } from "../../types/types"; +import emitter, { Events } from ".."; +import { getSkipTimes } from "../../database/impl/skipTimes/getSkipTimes"; +import { updateSkipTimes } from "../../database/impl/skipTimes/updateSkipTimes"; + +export const loadSkipTimes = async (data: { id: string; episode: number; toInsert?: Source }): Promise

0P@XNCH%t8cA38Qftcut5qzhNkLUzM{|ux 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

olC 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 delta 9603 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 => { + const skip = page > 0 ? perPage * (page - 1) : 0; + + const formatParams = formats.map((f) => `'${f}'`).join(", "); + + let sql = ""; + let countSql = ""; + + if (type === Type.ANIME) { + sql = ` + SELECT * FROM "anime" + WHERE "format" IN (${formatParams}) + ORDER BY "latest" DESC + LIMIT ${perPage} + OFFSET ${skip}; + `; + + countSql = ` + SELECT COUNT(*) FROM "anime" + WHERE "format" IN (${formatParams}); + `; + } else { + sql = ` + SELECT * FROM "manga" + WHERE "format" IN (${formatParams}) + ORDER BY "latest" DESC + LIMIT ${perPage} + OFFSET ${skip}; + `; + + countSql = ` + SELECT COUNT(*) FROM "manga" + WHERE "format" IN (${formatParams}); + `; + } + + const [countResults, results] = await Promise.all([Promise.resolve(db.query(countSql).get()), Promise.resolve(db.query(sql).all())]); + + const total = Number(Object.values(countResults ?? {})[0]); + const lastPage = Math.ceil(Number(total) / perPage); + + const newResults: any[] = []; + for (const media of results as Anime[] | Manga[]) { + if (media.type === Type.ANIME) { + try { + Object.assign(media, { + title: JSON.parse((media as any).title), + season: (media as any).season.replace(/"/g, ""), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + episodes: JSON.parse((media as any).episodes), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } catch (e) { + continue; + } + } else { + try { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + chapters: JSON.parse((media as any).chapters), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + } catch (e) { + continue; + } + } + if ((media as Anime).episodes?.latest?.latestEpisode === 0 || (media as Manga).chapters?.latest?.latestChapter === 0) continue; + + const updatedAt = media.type === Type.ANIME ? (media as Anime).episodes.latest.updatedAt : (media as Manga).chapters.latest.updatedAt; + + newResults.push({ + ...media, + updatedAt: String(updatedAt).length === 0 ? 0 : new Date(Number(updatedAt)).getTime(), + }); + } + + // Sort by updatedAt + newResults.sort((a, b) => (b.updatedAt as number) - (a.updatedAt as number)); + + // Remove updatedAt + for (const result of newResults) { + delete result.updatedAt; + } + + return newResults; +}; diff --git a/anify-backend-recode/src/database/impl/misc/seasonal.ts b/anify-backend-recode/src/database/impl/misc/seasonal.ts index 618b01b..8d2bac0 100644 --- a/anify-backend-recode/src/database/impl/misc/seasonal.ts +++ b/anify-backend-recode/src/database/impl/misc/seasonal.ts @@ -2,10 +2,7 @@ import { db } from "../.."; import { Type } from "../../../types/enums"; import { Anime, AnimeInfo, Manga, MangaInfo } from "../../../types/types"; -// TODO: Add fields to query specific to anime/manga. -// For example, if people only want bannerImage/coverImage -// it should be possible to only query those fields -export const seasonal = async (trending: AnimeInfo[] | MangaInfo[], popular: AnimeInfo[] | MangaInfo[], top: AnimeInfo[] | MangaInfo[], seasonal: AnimeInfo[] | MangaInfo[]) => { +export const seasonal = async (trending: AnimeInfo[] | MangaInfo[], popular: AnimeInfo[] | MangaInfo[], top: AnimeInfo[] | MangaInfo[], seasonal: AnimeInfo[] | MangaInfo[], fields: string[]) => { // Create a function to sort media by id const sortMediaById = (mediaArray: Anime[] | Manga[], ids: string[]) => { return ids.map((id) => (mediaArray as any[]).find((media: Anime | Manga) => String(media.id) === id)); @@ -13,7 +10,51 @@ export const seasonal = async (trending: AnimeInfo[] | MangaInfo[], popular: Ani // Fetch all media based on their types const fetchMediaByType = async (type: Type, ids: string[]) => { - return (await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} WHERE id IN (${ids.map((id) => `'${id}'`).join(", ")}) ORDER BY title->>'english' ASC`)).all() as Anime[] | Manga[]; + return ((await db.query(`SELECT * FROM ${type === Type.ANIME ? "anime" : "manga"} WHERE id IN (${ids.map((id) => `'${id}'`).join(", ")}) ORDER BY title->>'english' ASC`)).all() as Anime[] | Manga[]) + .map((media) => { + if (media.type === Type.ANIME) { + try { + Object.assign(media, { + title: JSON.parse((media as any).title), + season: (media as any).season.replace(/"/g, ""), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + episodes: JSON.parse((media as any).episodes), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + return media as Anime; + } catch (e) { + return undefined; + } + } else { + try { + Object.assign(media, { + title: JSON.parse((media as any).title), + mappings: JSON.parse((media as any).mappings), + synonyms: JSON.parse((media as any).synonyms), + rating: JSON.parse((media as any).rating), + popularity: JSON.parse((media as any).popularity), + relations: JSON.parse((media as any).relations), + genres: JSON.parse((media as any).genres), + tags: JSON.parse((media as any).tags), + chapters: JSON.parse((media as any).chapters), + artwork: JSON.parse((media as any).artwork), + characters: JSON.parse((media as any).characters), + }); + + return media as Manga; + } catch (e) { + return undefined; + } + } + }) + .filter(Boolean); }; // Fetch media for each category @@ -38,26 +79,32 @@ export const seasonal = async (trending: AnimeInfo[] | MangaInfo[], popular: Ani // Sort media arrays based on passed-in values const sortedTrending = sortMediaById( - trend, + trend as Anime[] | Manga[], trending.map((a) => String(a.id)), - ); + ).filter(Boolean); const sortedPopular = sortMediaById( - pop, + pop as Anime[] | Manga[], popular.map((a) => String(a.id)), - ); + ).filter(Boolean); const sortedTop = sortMediaById( - t, + t as Anime[] | Manga[], top.map((a) => String(a.id)), - ); + ).filter(Boolean); const sortedSeasonal = sortMediaById( - season, + season as Anime[] | Manga[], seasonal.map((a) => String(a.id)), - ); + ).filter(Boolean); - // Reset characters array for each media [sortedTrending, sortedPopular, sortedTop, sortedSeasonal].forEach((mediaArray) => { mediaArray.forEach((media) => { - // Assign fields here + if (!media) return; + + // Delete fields that don't exist in the fields array + Object.keys(media).forEach((key) => { + if (!fields.includes(key)) { + delete media[key]; + } + }); }); }); diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 4ec7226..89501fa 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -35,8 +35,45 @@ async function before() { } }); + emitter.on(Events.COMPLETED_SEASONAL_LOAD, async (data) => { + for (let i = 0; i < data.trending.length; i++) { + if (data.trending[i].status === MediaStatus.NOT_YET_RELEASED) { + continue; + } + const existing = await get(String(data.trending[i].id)); + if (!existing) { + queues.mappingQueue.add({ id: data.trending[i].id, type: data.trending[i].type, formats: [data.trending[i].format] }); + } + } + + for (let i = 0; i < data.popular.length; i++) { + if (data.popular[i].status === MediaStatus.NOT_YET_RELEASED) { + continue; + } + const existing = await get(String(data.popular[i].id)); + if (!existing) queues.mappingQueue.add({ id: data.popular[i].id, type: data.popular[i].type, formats: [data.popular[i].format] }); + } + + for (let i = 0; i < data.top.length; i++) { + if (data.top[i].status === MediaStatus.NOT_YET_RELEASED) { + continue; + } + const existing = await get(String(data.top[i].id)); + if (!existing) queues.mappingQueue.add({ id: data.top[i].id, type: data.top[i].type, formats: [data.top[i].format] }); + } + + for (let i = 0; i < data.seasonal.length; i++) { + if (data.seasonal[i].status === MediaStatus.NOT_YET_RELEASED) { + continue; + } + const existing = await get(String(data.seasonal[i].id)); + if (!existing) queues.mappingQueue.add({ id: data.seasonal[i].id, type: data.seasonal[i].type, formats: [data.seasonal[i].format] }); + } + }); + queues.mappingQueue.start(); queues.createEntry.start(); queues.searchQueue.start(); + queues.seasonalQueue.start(); queues.skipTimes.start(); } diff --git a/anify-backend-recode/src/lib/impl/seasonal.ts b/anify-backend-recode/src/lib/impl/seasonal.ts new file mode 100644 index 0000000..0bda922 --- /dev/null +++ b/anify-backend-recode/src/lib/impl/seasonal.ts @@ -0,0 +1,17 @@ +import emitter, { Events } from ".."; +import { BASE_PROVIDERS } from "../../mappings"; +import { Format, Type } from "../../types/enums"; + +export const loadSeasonal = async (data: { type: Type; formats: Format[] }) => { + const result = await BASE_PROVIDERS.map((provider) => { + if (provider.formats?.includes(data.formats[0])) { + return provider.fetchSeasonal(data.type, data.formats); + } else { + return null; + } + }).filter((x) => x !== null)[0]; + + await emitter.emitAsync(Events.COMPLETED_SEASONAL_LOAD, result); + + return result; +}; diff --git a/anify-backend-recode/src/mappings/impl/information/kitsu.ts b/anify-backend-recode/src/mappings/impl/information/kitsu.ts index b144c83..0f1621f 100644 --- a/anify-backend-recode/src/mappings/impl/information/kitsu.ts +++ b/anify-backend-recode/src/mappings/impl/information/kitsu.ts @@ -23,62 +23,66 @@ export default class Kitsu extends InformationProvider genre.attributes.name) : [], - rating: attributes.averageRating ? Number.parseFloat((Number.parseFloat(attributes.averageRating) / 10).toFixed(2)) : null, - popularity: null, - countryOfOrigin: null, - tags: [], - relations: [], - artwork, - characters: [], - totalChapters: null, - totalVolumes: null, - type: media.type, - }; + return { + id: kitsuId, + title: { + english: attributes.titles.en ?? null, + romaji: attributes.titles.en_jp ?? null, + native: attributes.titles.ja_jp ?? null, + }, + currentEpisode: null, + trailer: null, + duration: attributes.episodeLength ?? null, + color: null, + bannerImage: attributes.coverImage?.original ?? null, + coverImage: attributes.posterImage?.original ?? null, + status: null, + format: Format.UNKNOWN, + season: Season.UNKNOWN, + synonyms: [], + description: attributes.synopsis ?? null, + year: null, + totalEpisodes: attributes.episodeCount ?? 0, + genres: genres ? genres.map((genre: any) => genre.attributes.name) : [], + rating: attributes.averageRating ? Number.parseFloat((Number.parseFloat(attributes.averageRating) / 10).toFixed(2)) : null, + popularity: null, + countryOfOrigin: null, + tags: [], + relations: [], + artwork, + characters: [], + totalChapters: null, + totalVolumes: null, + type: media.type, + }; + } catch (e) { + return undefined; + } } } diff --git a/anify-backend-recode/src/server/impl/recent.ts b/anify-backend-recode/src/server/impl/recent.ts new file mode 100644 index 0000000..d2528e1 --- /dev/null +++ b/anify-backend-recode/src/server/impl/recent.ts @@ -0,0 +1,56 @@ +import queues from "../../worker"; +import { search } from "../../database/impl/search/search"; +import { Format, Type } from "../../types/enums"; +import { recent } from "../../database/impl/misc/recent"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const validTypes = ["anime", "manga", "novel"]; + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const type = body?.type ?? paths[1] ?? url.searchParams.get("type") ?? null; + if (!type) { + return new Response(JSON.stringify({ error: "No type provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } else if (!validTypes.includes(type.toLowerCase())) { + return new Response(JSON.stringify({ error: "Invalid type provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const data = await recent((type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, formats, 0, 20); + + return new Response(JSON.stringify(data), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + path: "/recent", + handler, +}; + +export default route; diff --git a/anify-backend-recode/src/server/impl/seasonal.ts b/anify-backend-recode/src/server/impl/seasonal.ts new file mode 100644 index 0000000..dc20e62 --- /dev/null +++ b/anify-backend-recode/src/server/impl/seasonal.ts @@ -0,0 +1,67 @@ +import { Format, Type } from "../../types/enums"; +import { loadSeasonal } from "../../lib/impl/seasonal"; +import { seasonal } from "../../database/impl/misc/seasonal"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const validTypes = ["anime", "manga", "novel"]; + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const type = body?.type ?? paths[1] ?? url.searchParams.get("type") ?? null; + if (!type) { + return new Response(JSON.stringify({ error: "No type provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } else if (!validTypes.includes(type.toLowerCase())) { + return new Response(JSON.stringify({ error: "Invalid type provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + let fields = ["id", "title", "coverImage", "bannerImage", "description", "genres"]; + const fieldsParam = url.searchParams.get("fields"); + + if (fieldsParam && fieldsParam.startsWith("[") && fieldsParam.endsWith("]")) { + const fieldsArray = fieldsParam + .slice(1, -1) + .split(",") + .map((field) => field.trim()); + fields = fieldsArray.filter(Boolean); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const seasonData = await loadSeasonal({ type: (type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, formats }); + const data = await seasonal(seasonData?.trending ?? [], seasonData?.popular ?? [], seasonData?.top ?? [], seasonData?.seasonal ?? [], fields); + + return new Response(JSON.stringify(data), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + path: "/seasonal", + handler, +}; + +export default route; diff --git a/anify-backend-recode/src/worker/impl/seasonal.ts b/anify-backend-recode/src/worker/impl/seasonal.ts new file mode 100644 index 0000000..0595297 --- /dev/null +++ b/anify-backend-recode/src/worker/impl/seasonal.ts @@ -0,0 +1,14 @@ +import colors from "colors"; +import QueueExecutor from "../../lib/executor"; +import { Format, Type } from "../../types/enums"; +import { loadSeasonal } from "../../lib/impl/seasonal"; + +const executor = new QueueExecutor<{ type: Type; formats: Format[] }>("season-executor") + .executor(async (data) => { + const media = await loadSeasonal(data); + return media; + }) + .callback((id) => console.debug(colors.green(`Finished fetching seasonal data ${id.type}.`))) + .error((err, id) => console.error(colors.red(`Error occurred while fetching seasonal data ${id.type}.`), err)) + .interval(1000); +export default executor; diff --git a/anify-backend-recode/src/worker/index.ts b/anify-backend-recode/src/worker/index.ts index 7f7cd41..0b31fe4 100644 --- a/anify-backend-recode/src/worker/index.ts +++ b/anify-backend-recode/src/worker/index.ts @@ -1,11 +1,13 @@ import mappingQueue from "./impl/mappings"; import createEntry from "./impl/entry"; import searchQueue from "./impl/search"; +import seasonalQueue from "./impl/seasonal"; import skipTimes from "./impl/skipTimes"; export default { mappingQueue, createEntry, searchQueue, + seasonalQueue, skipTimes, }; diff --git a/anify-frontend/src/pages/anime.tsx b/anify-frontend/src/pages/anime.tsx index a7e8e26..a45b7a0 100644 --- a/anify-frontend/src/pages/anime.tsx +++ b/anify-frontend/src/pages/anime.tsx @@ -149,7 +149,7 @@ const Anime: NextPage = ({ seasonal, recent }) => { }; export const getServerSideProps: GetServerSideProps = async () => { - const seasonal = (await axios.get(String(env.BACKEND_URL) + "/seasonal/anime?apikey=" + String(env.API_KEY))).data as Seasonal; + const seasonal = (await axios.get(String(env.BACKEND_URL) + "/seasonal?type=anime&fields=[id,description,bannerImage,coverImage,title,genres,format,averageRating,episodes,chapters,year]&apikey=" + String(env.API_KEY))).data as Seasonal; const recent = (await axios.get(String(env.BACKEND_URL) + "/recent?type=anime&apikey=" + String(env.API_KEY))).data as Anime[]; return { From 5dfc2e4166ab5111b8071dd6f60cb66632e58867 Mon Sep 17 00:00:00 2001 From: Eltik Date: Sat, 9 Sep 2023 15:53:21 -0400 Subject: [PATCH 24/77] Bug fixes to sources --- anify-backend-recode/db.sqlite | Bin 1216512 -> 5648384 bytes .../src/content/impl/sources.ts | 4 +- .../database/impl/skipTimes/getSkipTimes.ts | 9 ++- anify-backend-recode/src/env.ts | 1 + .../src/lib/impl/skipTimes.ts | 2 +- .../src/mappings/impl/anime/animepahe.ts | 2 +- .../src/mappings/impl/anime/gogoanime.ts | 4 +- .../src/mappings/impl/anime/nineanime.ts | 8 +- .../src/mappings/impl/anime/zoro.ts | 9 ++- .../src/server/impl/episodeCovers.ts | 75 ++++++++++++++++++ .../src/server/impl/sources.ts | 10 ++- .../[id]/[provider]/[watchId]/[subDub].tsx | 3 +- 12 files changed, 111 insertions(+), 16 deletions(-) create mode 100644 anify-backend-recode/src/server/impl/episodeCovers.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index a434e0e4fb194b3a0f8bb7e2567c382b35081a9c..4de563ba0224c8fc9c4453adc44df2ef2192ea2a 100644 GIT binary patch delta 238296 zcmcG%dw5*uSug65WXspcBPVt)wli{bX;RCcb(wW>;@Yz0yX82R9bZD*teIIOO(e~z zGnzPZ35iQdp|DRKLc4&T4G9!B99n4Up-%V1hLp|2xjY4uXYb7e-ITh`DbUmIl5QY9 z&<#Dm_xslRE^Cb@M}HjksijD>-t}GH_x;}Y_g=o|UOMsI%|GwEe%GeQSFKuIS+y$n zhpSfg16Mr`}xTb&0 zI=tk!&kPiPbm01j2d?LC3|#N~myd3u&kYQ$8W^}`^DUcSe0}X>eVcw0-~OoYmOuO4 z>udk4Z}qkBT^xKc`px_L@7eI5-}S*yJYtl5%QU0HZ9{k8`2KzU`N60@yk=AMgA;vg zqHS;HFWvaXf6TuV6j$YTeZJV=SJ<9=S7W*`g&7sjw3<(bmBqq4FNdvWVY2@81CjAo z{%G{2Z9{hsh70@sl5a-FRR3)spYLBAT`uM}tUWgq7A9KF1^L0X^g+jPO3@2OZb!87 zjr@jn^r=I^;^JKN!uRsWBt6Gp)diBlxw&+Xe`mFEYs#^<+)l$_m{Aw{Qd$pQVDceC9mOR_7xqdAyRZ7vH7ILMXPRT0S zj$0}gi_h!^+kwS)fmMz8Z7-bfKXJgYYi1C5Ry7DKu2n8MX2~#3{LV0a*Q?el_=9EH zMk#R0wOU|Q%cY>~`9ZbngnrFuFWTWaMZ0KN=@)q>O)L7!ck{PLkAEX?9drV->Uu`8 zg3*_Yo*fo_8}soE*RVa)F|A_Nu9~ic7nn7-R`OiCS~2{R4U{--@1TRIp#Z5m+TJtQwwKEAsd4bX*T}F6!&(n8}9aF7=-{ zSStFK6&8zjwHDNhm9XYjF!xGmm|?k8u7qy6TC9}~$EkX?(5qJ6a@n&>UZsLPtCTE1 zUPJuO_bgMNnd!!?@fCWLXVi?E>EQ)lShL-rTycxF(68D)7PI2iN?6q}3{9-1>lkIX z7KUZpG`&jMGpb%tjo;)OmRT}WbF!@XP1nDP-Kv^3%P~waai!{D{d_a<0>5U0G`1>q zv1(vO@UrcPCicxK8Tb%ZFmUafQ7$EKa$L7qOzoCkEONeh-N|i>KJ_?+i zBCHu0uoaX7tXajdiIv3P$v3A-5$uG?LqWuo`+s;8pD!_9qN|uz-sp zTQ%FRRBE-NZ-h>{T7m`vFI6jHSOkxjTp!xZtYQ?LS>6Td^daG?sd~1@#Xxzt$=|)X ze|Yyn3ll713C)UWc+gu#tL9h2a)AH#q25Z+RzcM%)=IuxwJ~uE%xOd6V>Etf8CE=R z)4)O-sZI54&OW=8cU$b;IV;Nd55MbR)iAvxs9Ts-LGO@FjvRO5auv9j%pB3M$ z*=4%|6s5*}c0U+dD_ecy>Te>-p8^8V_WH#xog*tz$Y$J@uFN52hi zy?J1GVEv)FX0uwj5VUI16W_`2zt<_*U?lb>6fd5tj8D$Sk53k#jG%wF=8rTxjcTx1 zZ#HmtHXC6(dcn%wA8r0le#C==@yNS)4?)9Mv7)M;;ydlrfl%PVPUVGZ;GFjXlZ-mZ_FabvYu37qJQKQgpEdha-tQn!DJl zKXr0pQGar5HYgk~M=zXMz2oE48`nnP{`C4gqwAG{J-7Jo=%JaZaC*r(dFWI*8u^vg z$BwXpSfdkW{!1udhf4d*~1*-YBeKz{Y!&8 zqTe4JTs=4y%wpqaqDQBPw?=37thxUV{VC`Rm;$AuT??X@?_axR9j5zavqQ|o9@+fo zYu|Z$(Y4eKb^LNr_AMifM&>u~j4qF^o!&T!w=4#Qb3uJ3WZQTrJJw&~Yy>LN3u`x7(Q`ktdPDTl`SlyuVOa}8!z8H658$H+~>icSbl}yuG^tIg^cSf7n-ZBt9_si?=hzif- zAJ~qMItKQkQe=}U?s;-yde<}0ya!6px$*MOp~rL4nRgBjthUXfWko+Yxo-dOoEUm< zAM-;F9$u)on^nj(S=@8MV%T0h7hCbt?miB?JB0Li7NBRt>KGg@1BPAEE!xq8PxkMO z7T(Nz(bt;&cSlV#cP!fZ-TWQVSIyis|EXamKmCjN>F@u0{<-Lbe~*9i|A2p9qJQ@O zWB$F-&A-p@iY~ahC;7AAbaMgw-Mt|n>8N3->hHll8f|0`1b&Oi*oJ zk^U5$LCJ&x0LO28^!t;!4Yyus1&cFLJ*uNsz*)gga%udnRY@m4Er*V~JAe0q1`OlM&sT*S1SS7_1B zg{@YzMejbaQ6aq)z1eA#)qzbusFC~PZ2yiUhVMvHCz^FyceY;43lB&51_G~W zOhfhxQ_ap?;cOTzgss9@YksLPhN*(xGQ_b_J4bz2(mu2V4ZIX!OoxKTY*63LC_mb% zW2MGGoG;LNIp65a_wqaU7(Sqp#Bryop1aa4OjYV(V-f4!-VM#P)M?d0_FOAq;DWly zzQOjYK^hef z#VW1Op=NbyQ}=?;W7N&iOEX#V1xZ3xt+cPJy&lZfl?r3 zYq8Y{rD<;#6)8B5gK?S$Iu$M~bY?r?X1pMvDbTpV=F>}sum9}xY~&T?4Q|gjXd=^@ zU%>GH;H8t{e9)@@!As|wofg?yjYX^+Mp!LesY4%uSLUF(QrzuFBsz!8q9QuP1SGX& zmn^_EFB}S|>kX_C{ox!TN`+dhIbSf0V&M`brd=4D?!sZD-#naLa_J2dk51H|s?+?j zD5t|Kg>k$BSl8~t$$Gm3Tj+c%n86O|3=8*!slt2Bq9Q_k%YsIgvBA->QODLDYA)$) zfM=QHY#%j?is(#sraP_9d{FR}F+l{IPlfHmBb}7Wq5&l5hzU1K&gocvsoAPyR$==9 zTOhVrO!bhyYz5O{H9Mk2W(-AU4uxQdrC=`RMaDFh7F5b)&%$;-`rFCIY^0LebMEBtYz8(@=z90$wB7AfduUd!%p}dbJhCYCUK`lO)GJ zpw{{{tiddoku=Fks{G zsrnoVR%@=gxJagrJjj4bGA;)Rh09N3C%Ja#$5`P4q#1_5MA%*kU^HlFF-UM`-v=B{ zWzshME#jz|I?gLD$)}+suycF%>>&=ApWd~v(V3guz3W$B>MyM45d6he0~g`FpB`{; z>^S_u9ow$G>zY-$d&jj$SN+t`2QTHHKbpI%@A1Ri^7-7gyFb{xW)1fJ{I=ho=Me_5 z@@x=&adM4uXWAJSZa&|RPOKyI~J&#@Za`fH*K5);5r>(2+JA2tO&mXxI75;u; z`?F(2A0rPN({uIq3|wXQn|*~bXx3(Hi8lLC6M#U0G{gml4dCMqz!y)EV?B0h?BrPC z>(5<(sIqA7yh#E#Qp5Y(O|SqLm6$>M$0smQ4D4D3LDC(;Q{TAzPK=O zG;accb?lM>RM9WOXDLO&*qSW^v@DVF@ESkb{Q318`bwqf(GP9f5}oEQ(^WXTD5C83_f1W11 zd)I5%U;pT9|NgblB%eyYXVwN(;x%XA-)^P(4i!dwZpeF1oEf7XDl}UQGXahPj&~He zYxni%ey&}ZtJhdOqNW^X@9)4u!65>psmvlK!D1nRiCzH>DBQx8nXvI}0ms#R7%sL8 zGf+@9cG5G7)q1-ETO`ECnuSGp;Pi?40(@%vV43Wxg}H$AMWeu`x(9P;Lpy^uBxa5n zN*&EyI1TmFCXTB@;bU0DbI%s$mk8M+qqR^DVZcBO$MKz3$Obasgnq(nA&YRg*KTYPP-*J<$(1>9@A8-Z|*H zh=u?^dSS7zxbF5Z(bpeu-x`hGGxS4w3W1IuzkK?UGnbc|jpC!nqmgfIdTI;TT>2lr zw$#6nXED>!`uVF1OH)r@x@w+&@%1-vg9;ctVA>93Z*K*5L+gETT&BalrApPcD}iN~ ztD)}%6|ZC=I)s>5)wc+ij^4jEck9Pr9ym~>Cpr8XKk5M5H^Z7$al(od_=aJWtAO!o zTP(wLqOniqZi}A#K>vxgcG1~uSn!XE!irvhc5rXB@V~FlED1tWRRd;C)4;?()e9#lp2=#LE?f6(!Ld-Uwo)hpHF(_>BNf~kX^ zIAO^iJPGlN#{PB9_UIR$U9;=Om%cn2ed;eaT>?rDfPQq!x0jC1UcG#}c`}T4er5Ar zxmga@ZoYTzn!c%-sPN^rx8b4P!zBx$jM01Fc7sf5bn?=nD^J#) zxhEIvzCMa`aB*PUlC9Fj6aNvw-salIfoT8LO(W5(#=6ny@BVD)64(LajWQiMQe1iQXfCu9KUev#Dx~a&J>s%dN>&{P(c+frnPJXi=d^A ziU51>@_>gqD%^`e7(#r-pzK8Xjca!18qxd*Rv%i!KgS_oz7`-2V=8+2(KWYoVAJq` zf|wEkw2O$mmR;A1KHC_$dkq1xK# zQ@iNZ%3;L|qH9CS2F`9`yUJ#Ask8Xv%YXWC^ybqW2DZA|G<-0>TZTFK`VVi~5q;## zYu|U{*Y>P^JonQaD?fMhm0!5|%I~nBKX&t#&)$6H-_b9>@Dn#*`Si_Ke(B~b zKXdbyFWh`3VjuYJo3G%J&)j?kpS*VSmEXAe%C8WeS6&81_UtuKf9-#M?H6AAt-@>n z_O*|__S3KZ#%nL*KY#wU>-4Li$B&=D|33EGvoF3z7S?&700n^XCj%I&0sRC%skbqi zcux4uF-)R8lbtUf7wdtQ!+$;kC#1qx4vW=hi-mpTf5bwv#i9i&Og+n%tk(#3!2r7e zV<}b@U@90o$n${>MK(zT9{Q8b@@_Jv8n7N(h4ASGjxW)l+Z}*sw4X3I%3-11{Q7gh zTIs-DI#4(U>neB_9|1Zt4GW#1xMl%p5MWF)Twr;??CQWpn`6q71e{0$UTpF#fPG-2};?jH8%6SPq}X;SO}5SqK{d z#t6M7eMpl;_I$SpZw zyqL>U0ink$h00vB9k!U7ieEBQVw0pnR>P;7w5Z4jBDfFM+dQFKuuoy1wVU%HPyZo< za1S%bf^9Izpol!p9CP-->lNl0!M4ogf@S8Z<`@u)B0k9eX4-})%(2+HF$}w8Mn-P+ zf#}R1^$opuWeh4@s5h=X|HieK-?;Xh|JU#S{NH@?_wd6vKJ(Exu6^u{YajZ?kNx=H z{_d~iH-G!4m285WM#Ti}lgfXILy=@;j~I@4rojyKzI z4oGQDv;yM2kAHL1)=>y_nI1kJ!aA+b(~l~#P1u8f^wn3R+<(fwZo3XxUlNoEi_}ZIWqc=a%e;Pr5-7qz*5TQfEu@RBIeGLWk>F+vP z0OJ;UDM+1S7II~0Yz<~URE7y2l%w1|tHT}3(5aSd2%|}d9-yC@U&DEcObIm|ueQwQPtXlIIx!K$- z(jMQJ>s#Fb8uR4p8-KBN@cwlh8Ah}2%~k8(yk!X4k^B3GzJQP2pX45$~j4&8R+leZ2UeK){~FZbOF&*Eu%Wq<$Ts{X}wf4n+e^|N^G zNBRc-7_a^Fz8kao!SCj7gg>_S7uK)eS2)_L&(A-}V`T@X6Hw4XZVp&{Iq=+Y6y)n1 zRJsBY$3Px%=wmo17%gXg3fW$;O!IS z@guE-MPwT78Wj1|Vy8+@G!GWFM;QM0tnx;RnJzm$S3!;mz=Q1q-GWE}oskssqC<_| zJlSkE06Z2>(<#9R!~JE3CXBV)K^wk4JLWD2jWr7_C4h~ks*J_zITi(bJ{dMzOCA0m zB*fNOkcA;=NEVuBN)X%G#<6t-L4+8JCMk~tiH_a#O-fAXWW7v@sYmIk#=(p}BlDO+3yl$57XPpA4u-6W;6sp$JNI}Gg zCa-@uPBh=DgZdm_AJ>i2-G0H7PH6h_#K27oeNsiu$7THh1l&SxvF!XB&_kT^ga@;-%lPX*#B3WQed4Di1S7#N&25ms1WjZ5(q zg?+D3+5y8t8)?Q?s&7;T#s5-9cxY`YrRqLr3yp&=PV$XSi1^q?}Ts0*_7;nxY z(}BXJDzEhveNPd63fnOC%&G1!z~m&yf&GrftGJ?}`B^QwzKk7|m`!?ySwW<_l|6+nkL!d` zMWIM0ZOLIoYeAXko5&FV*(M_XbYO?`06o}tXap%9JqF)Q-(NC*u_xFWzFfMY1FS8M zRgJZPja87-L<3c{rPWjZY(@UC5tIvrc~6FoCP_LF92}c~P2vNR?9gd`TC>+E>cs9T ziMAq%W3=u~zT9eF7P5R0!NR7qgp)0E%^HqKg_&9EhAO;lbE!h%&_A} zV}RVZw7GJYhdvo4MHFlyTRvcnG_|wgVlY>SMgxb&IcIE-rH^$I{FS9i;DdH7t zfcxUSLq0mBA`*Bvwzx>U3}HCZ!pN&&TArq-jg!&^izP*dI7zG!Oq=-y@N)}_WeNZ! z?3~I>BczOi^w1FNM~>@0qofGQS%w%Qd5%UvTyeA>kf(Yotid0Zzh+y-2&yTFxqr^@ z+>1I%xpbG{rSI{=wmlyC{>^r>crnbR3^Tm}v~iVUbM z3bYTRkBk9g=hMimLUPu^0#jaL0bh* zVflu&I^;$%s}xBoQ3mu*B*941Y_xzuF-EYsO!wpqdl)OxtiiH)Dth9d^V<|sMV7^Q zzoF)B5iN4`3x}5wTHv{YP!q_FOmlUS4P?KXx5ac6*e%{m@C611KP$FQT48vV7zgeH z;2YtTDkI{VT<_t?w4jYaC)L1d4(GXDJ5`JGGNs{B z`k_dwEH zV*@^PCo@1U(R)orqQ~a|t;ch1!RM_&iaCp8B@QmO&`Y28t08flHX#FN(V^pX*hq5K3|9diL zFz-h3*3F*ajityKkw4xbsYUP+CSN#@cZ#`URVU%T*XPKmPS!j#?VccxrO4n};MjGh zdgxTg5lHiu2oZP!(bj32B19a2YcXD)LIxP}+qLA-ndsnK`QmwLdz(EG9!rs6F*)RV zBT*fOAGujm%}NFDI|Q$p%}*uW6VtI&xn`PmAKSBI&BakxK7@nkB#g8spikC<;h=)x zv24y|QF==ecG@SI#d`+40EdUdyq5rcBCbChaG_LSTeBx*V<}RPbZRm?u)!gDsIXo6 zMkU#Orx5K1zbCenf)biNks3=;2je&z<_Kpej9Wn$Ml`!>0&u_#+W?UpZuw?UH_=iQ z1g#R24i=u^r)GTUl7dLeSrjdU0%#bxD7RPifHJyR*eRw14JKHJ=`|!5&8Jf8Eff|q zW74q{X^%Z1hPKAhD9-wZflL=>S(T|lN0`y8vi|GcsC87-v|@_Fb`R%aT97PFa-)UP zPPuG#kWqomQ%+bl!(X1v?c9YP3zFthlw+5d$Uuf*bWn|k1AT;0lzRz9S-SBny9S*N ztb}mCC?T}SAk%9IiG5I;{HwC#fA4ihisoeb*ampi!Kw@0ipZ@kk&eGy;**g?qkWuKL7h6JVfyxnpKq?q?sNvqxLGjyo3 z(!6_F?GXj4XqTCg2;iI8s;gy-m*NE75mDXV4n&+nQm#lqro<&I=wb&*a1{js$cfbf zB#&3QL{!6fAM4)&n-m8DrMtp|hy2ngs5J~z%HWQxQ83$Yr7$*>0<&T&)~sgp`9>KN zrxX`{%4FY}6t+Yg-pFqpA$%3JTBL%`QARQrZ7KlHT7{E9AU|hm$q2~nqqn{DR@&K9 zEE5{%CpRt9QtI)Nl^r{jV_~d-${i|=5biA-q56Ut+*1@jk3zBoB(7_sl~kYMcH16B zlQV<{J4xRO>*=z!*|kZmwe4!T3Dh=NlgAPT>LHm9+ei#_kLryGOozZ+@;1lH;8@6c zh6Bj>+NP-1Scy@AQRdU!%RuF~)Fx-c%3M$fibUJNor@SP5R#nPLGD-Vct=)sLJdH( zA*m|1l)H=|;hquIgE$IarGb-^fTfaEv+5qjMYDTUZ{aZEUVQM-A}~?;;Q!zyG5R!j zaA#qA^!>i!joWF`D3^i>P8oH8gL*y4*lPQ3)j=?9n1M_1`$BlOU`dKWV*H1n4w2TD z2&}?p$ms;{Z@*V{4`MJkt{E~c;hd%XPR~em)7pnsSKti18HNEcX&;AhKp`?T0TVmi z07OWx{GsN2xjhrk&GD*7h5HQ7eX2_UfDmWPsacif@dDI*@HV3r8b2e zN>&8ItpRK&SA|o;aQ4hz)~#yXP9l<6fsMi>T1f(-j1?ej9Mx3U)nUWAQ&D{|z^Dw7 zglQtUk~wxv$%v|T$}tl<4`{t1O|ko(ik>3)&}s%ShSL0P5+m-sPq9T|k1ybpbp zTtf*ak7f)dFDgI}?pAHgNtCk#SdX>Y5h_m+t_hC9AC6vs4^Hj({d4|yMHrZwx$|9$ zf=rMqAq_FAf!Hz#}sD% zgO^ZHFpqFhigN@lu;xy zhBl&x&>jIOMn_SB;mfCxVVM}$+Gf+aYpKz)F;pu7OrYCubREN7cg1(_ok%~|N+*scbrlG7%ELKwz7AvK2G z3tUhmQZ!T+^dzTV*qO@S@;KD?yVW?M9xg%53IZ>S>6tEnh0F;)+$(JS--L8>J?9f|Wv!J)944>mddU_49& z)8v{0ubH|6FE!1=h-STfGr!|O#eCogC~N_Q3Mn80ESKD{vH3EJRp9+ma*-mHC7V&$ zuh$m$*by+z2=l=fl6C0Df0Oc|!S748((%vvTKp=38s&)|7a6oRXV0VE}q4R*AY%Tw!UG z#}V5_zG;B=B5c73eDMlImoiAI49-r@TP8;+T8?w- zJ*SsOa215;d;`5niS*G{r#c<01vwSwXb8`X9N1W9m9^}dL#?JzBUieDg1l)a{Q#hG zi~-q) zXpBxo8NyH})=PD$$<%bv6YLqIw1k)-6HuV02+0;$VdW8c!qm+LW*2)WOX@u^A{c~P zs6_96D{m@H(lgsyO}3U^L!6RKiiT$$Vfn_B5&@ZDjh@pzq*%?bR$?I&!5lKd^qfIb zk4IplL2L1n2xb7tSdi!TQWt7|HDFQH>asR@+PQ(%qL)k{c+O}mobL8AF4Uyz37mCE zq6X6?V0cQU9}tjT(oKm;)#D12_0k$@IyKm-O5N31fQa^*g-&s%5GKe3mjhf(=gEo( z&+VlV)D-F@)))KVg((Uyvo-1(pioQ_x0hy6v!`QkixU2(I)E&YCc(urDL#M;Lz!AQ zo)Yb?$WG5hYBi5~tkFPfF4qQ$ZF;I6;+$Hgqo)<6*SojNdg(s6|TE!NwegLlTLf$&7jTFlNqP zmh<*|WdW%TG1(@f2qy&*lN7_otg~@f{mJ*HL`I4nMsx z*JMVgTr1_2^?PX%Lv6>&mGy3LF*^D)g0w^&;H7hkTR+@YQ^cuf3r<6A!D$p>fGYWs z+B=(@QHDYP(L_cm{Qi zvi`4!g>NBU-?PYjW>b;YE;?NGloKTsLoc`xpwk#cg&ie)HyE=qb-+kVgv{rO4Lc62 zjXYz+maPbxW~3-tKB7#RK<|w?=0=XO3z4636sqhtIRxq#K-I!fseQUb&VsO?gclCjrNb226g2BVZ*#S*)#2HohZR{%<$cy4fU{rXL?33F?X zu3B>xdA+^Ocz5^M`ZKd}tC~I0rwq;n!wSC4*)kdSj=!9p`clHqd3C zwd3sC@gi=p;q!K!mu>&Zm8-M0tF1}ij&o%#WT3d>rkzQ{A_OCNyC>3*tU>4h$L=z` zW#=)aXJ-cy=FvuT6y|z+CZM123u?ENw70@<&}NbFm_1KEWj;wKAwt+sk#T?E#%o{5 zTTbr5=)0fjzc+gB4_7~QNxhkva9#)sAp|L|ZpN*~P8=SN6w zdpCaYPx=3nyMdnndsjyXmNu@7_I^8m`;EWrAO6@twDsHh&Fo^X8#lk7|4u(Wwdcl9 zy>qxdc;l=04*$g3Uo8$lLBD)QH1^>E>&EZjK0G!UZ4Pf4y|HQQ@Z)RWfj{le-ug1p zo_>m58Z$A8TM|zHxBS+vlj)ZE6(lLb5KFFpxfgd_nU<5KHP-g(jMiBDNj-j!J*5{!G3^ZXX8EnPb7qsb6jBc53^eBV8|m7(Y_LW@jLl#Ye-id!4)Lm$v=G3@o+6hb`s@@O8ZIn{)x%s)D0rJ&rSj0 zGQIhgrSXes)S4YjayL&f=6Q1w?v>hl4^vzSO*5~8{BlY^PhU-^Qbxa??0AFm$}C&2 z%j1>lndo&Vw^iO(C!fZJP$e_F+5y7N?9!jh6Q0+Ia4*!h^)xPyg2>&P!VOO)TuVV; z>TU%SmE-aA6`S2+lidEN9CWh4C2rmdmzO+IF}gDDaKeo$YyU`q$ObTR(@pz7Bq1&6*o`uNnFpodG$t z6`X_)q9~U*`=~v162C0swlQg;@WLWid7gw*lIk>^%Hu5*8R+LcNHP0kJ7iAT7$yz? zFd>}HD`dCArBF{&a-4V_vu=uj95Y3>oA{E$B65?s+=+)okZuMbNVrD#6&{%n&_FRm zDap!H)AGhpm@9(D>|TPx(dl{lps3CP?oir3=?gjAv$Z6&3u>^HS6J*8sk1wo2-2dimtIzDvGF zfHpv?19qJVZKNpU*0CbSw(64ga>;Qol6=h+?h&Fkl2{>R7Q*Xcyv@^Bh;7in2}nMx z!ew)rRCc_VXO4Ec@+C=JifRFP5-_EoqE3mC6rlm^LN5f*REudiqB_-SEkGxQRbaKW z6?6^C<)F-xh1r^j-W#CZ%jq`NY{eKqLVyXy^lUv&23JGacnx0TE@JH<+RNF7B_r1$ zRxo^=BznjdqSh%01~l5}2uxnQfCxaimv4=Btdek|2T=$fH_stPAsNuQP#`wwaNAQ> z)jAqkosK@70nouJeTSop&b;?Qmz3)r<_#SbF&Mf?vX>@Mt7>S=c+n*dS>h#1nGQ}J zwfziRrX!LEt)615CQZij1bSLLN5IDzcTd?=6DR?h(DMKjX(nj{Ix@_=CsGb?J#>M5dX66YDz>HyD(SDXu#&{jMo zl>l{24=6gu>M62n#%F@A3P1p9PSin$pV_dj_C`S=zj)(!?-?H7K%Ua!fzKC)`!{bj z8iW$eW9yJsK@F_uaTg&!as&#D#q25KYQktz)hEv}K4V_jKuII$*N<@t^Q<8yq-W<8 zQ%y8Qk_j#xpyMm)|0I7CcY>l_6{%vy(kk^aI$=x+uGIN|U3{jsmsgEuz_i`i`F3LhbCr zGcDpCSo@?p<*4HvOA(^Rym57JUE$=O%0f-6CD9n8lx~Bo+?4jxXoChY+p_XSSS%xW1SUar-2eg&&YX|dRhQ#0xrZIWt>wD9CdX1wCDv@ zIAe|3kehGHj+A=Jy_$(j&P_9}&H^o}4##F7kLpyXHQVOhOL<^F&9tSSC%&4D%bgwu z<-%xL&X}817Nw_1r+drL{cBK{!XiK4m~Bv&+*lc5h((m(Csj+3?sIC(Ohv*=JtbUi zKa&_;(D4*hC2pfq95{u_F7qQsrQcJ+)h0B@=gE+6HVEp6F|F!l7<$5{CM76BrntAD zrgBtkgYW6MIv%&k{ zGw&+iRMvrsDw60N9uH9&gj6?~kEYOcSgD9*s)@JUL}!7I6UeBAhC%b6m=B@5C(s1~ zW(k|J2&&-v7hXYvTVa%xS|u1pZ9tGkK>j~;8?`Ax5R$$#LfViLRB6mqlWDb!?Bb+& zG6<6d1!9Tw4RpB0rArhvN8&y2a;OfH!%VnmLUEGgL9&Y0WS;!|h@k-9nS#rON-P1H z)GSySbY}NGRWwOv?KsE;?^5x1k8~6u0#_~}NA4I31Ii(_Kje-eGv3t^aiGaD)m&DQ zO~L0xE63YB!&M@=IR=MgHfYDvqHRP1Ih``q{8e^H#g%g8a#5l=4qC7pV=?}klk^uV zdp+BMj25U~ivO7}qxKqto_3pRb}Bg)7&j|#B$t%uFC&%oU~;2*sYwJnb?Wc*s=qN@G4(()n9nr{7o%UT4;O2ECeH{-L2ES__?=mB;oQInzYxQR-d)o@!1 z4Q;on=6T}IVVpS_0kY)KjpY!kA*ZJUUQ~`0-ZY!xUU8xUJWj!YSl$KEpkc67G`McK zIN@;t98Qu#Wk>sN41U2G#faAFF^4eV?`g?80x zCChJTK5VLKlQd_3vcU|D8v`aJ$!g<}FVW>`&In_(13A4lC?qHLzREH6c1fSC^12QZZNMRnP9`GUeXmI$)c#XEfr2h|_YSJOGqDbv$ zt|&;+FO_<8u5d2!+ef*Obr~le41o6)sFTPbM-i=<*x^OdGBAyDW~0!P6H;K7o@s-o znm33$j?wKx1R^BULAK`RlRv;ru;%z%L{*zz?3p}hs@a2>L;xVQ@JO5r#H0r`;4FB+ zE&F3=#!z?+{zbTtRL)#;y2B(@S$cWx_5+rhFc|k&6PHSmdRgEM%g3y!aCGdUHU(p9 zDqy^r(Em942|N&2W=}2DTlGZ*-mu7E6{PJ!6Y@c)nI8>(h%hcBkwQ;<$5oULe1o7+ zvtT@6?2TzYQpNi3nFMI5Nq|&=$twYQ`cD%0;R{Q+J3A9%Xpg^WM!JAKlL2voo}ABE zgSR(RbvSE@OBYDe`cQm>V!3Dq%pKej-d{s~TQ3B|Qu6>OkT}JP6?hGJ?9S?{9qr1H z5Q>t(X==}z?(hc|r9k1%Luv+KS`)|T8*PCqRurNL2sUBWynN9#UL;XPijX3zhY{jK zAHoWt1C+_dyv_9HZXQ2NytFhmgLN+2xkJ64TlTezL#>SAaE@+ zK`e+)<=QM2exEQz*xlJY*&Ns@&&TI0tG=oi+JH+zC37EdpusILKZo6w8{iLV9hRCJ7rL_2x&+P7PO29KVQDvm1Fb<` zbK!VgUl6x9#U2F&lEt@cWBF+3P6hE@>!Ky2jf~cwlTr@TOVpZ#^(*25G`@zyh#|g+ zjUJ(>8OKS4&M5Xm9?>&dZWeq9ybN86lJ=I+K4@iy!j&byT1|!9dI5}<+PC(61GgbT zmmWvEaCS`*b_185wL(O5>Ns^p-47Lqu=5ywqnD7wS>Z1gdBQeQV0*5ck{ZCHx@1_f z2sB<3<3?mFke%7WkssS3@_4}Awmn~<*s?-iiE#-kMdu$;@p^>Xsxb*eE6I8Y43BM! z#M2C;7x;)oF}W$p@}Nx$JZu!GLj}eBERQHoUk1Poqo*=Z6Ks;a8e*l%4m2!+g5g{Z z<@cX&of^*z$gE0FVOO(n690*B!${$D^D6Fy0>365 zD451!^wm|-MH~j0y@+gPnLuZ$**WOW67Q{GS1x|Bu43iIv9m6be#7V~+-lxV`q0Go zLVwKFkwj1Jja7F^h$PC>N#neejDFL6_$aTQx=78$Cr` z&Fo>}>*TCT!V^b=`T87CY;`(GT!XzznM}{zAGp*~EaSz?HDX69)V@bvh!_%vh^hS9T`E^=Ds zme7L9+`6+NTG4~Yc!<7-)>5?M+w>n(4tqG}D2-Z51`S^#@l%-&;I~fkxyTSUaOqyM zqGkorTqZ(lyiX&?TmnQD5>poasTkTRFoD=QV~7{qCv{Fe)q$EV1a?xE3H5zgKU~ih zy9Zp;p(_bRPGpGO=$SZVsfj~zs)H1nb0MyJAg2($v*s`-anm489W}TV!ofMvsMY5X zyJIFCtsga-_TI{SG8F;`g#}d$+dkY>?lZM6+p=vKsQx!5cS#vc34={J0N1}MURnf_aO+ax5W#6|0 zmYOrfy4l0G;DC0Bn^VTHTNDA&`m50XsjQ(g*f1@{v?a2W^^o!``H+GvW>GbXKqvY(Kwi zlk=7`YSvS3=fi5MkB;~&MQ8yk^OP1&_cLz2zY9t7x8JR1@|+HzrbeK2H6#}Tc6SW9 zBIG!ZAOwT}v8OCOJx6+oyyu7x2_wjqG~)rcoWmWiDAqv)3Hy?6 zD5LNn8rP9bJg8>sh`mc@fVQuMK(poI<5ekesd~4Xh@-rnvzd(5Gh_>^LHRh;yln=c zJcy^o5B=+CT)Wlu8-9qOe>2j*xht_qT$*rNc4S<(_NsX{oCZ@?j1^%<@K)4NOoUfW zEd;X2Q?b14o(G|tWg|>E+GvK83%E`79h0KvF8fc?WvfXwTo4OTpGTT>6+9a`2FsFN z_!TrjC^En_Y6wWK-fgKFGjeM{AePNIu1dfbYsVJf!wvlfm_MyoSa-Ue52(p8+(9}} zxX63@V&ZhI6B;@TVV40Wlw9E6q=zgm4F=mNFHhjUZep(RuqWN8gaQX9GARrg*ODXx zLp4+K*b`e_AeDz@qi_loA2AIl+cl?pl zSvp)avbrR1KU$=F8rcLaX*#oy(9YH{sI5QPvQ0?6l7)JC1-bKKb7Kb zi$3)@_V2NOR37zEC)VXrIl0OGREKwa^u)LFo1(|QhoVnZIo^8`JsJSgby*k5HI?K0 z;VL8riz+IO%OY^5J8h~Xq3-W-Dd#X?a;u2jzOn-n423F6jVd~S7jj!jslAge2a#}0 z+?qjOvU>08=q15j6YZu(0!^BU#Px*4eQ4l-%Bbv$UJ_h3(FT|OkMHO2RrVbCwQZHM zD{@J28H!u?M_>LQsiz#&>1AhpX*}72i8lD_m48V;<=CYzlN9_l(FT8g{9o~u%3m&W zn7hnN@Yh5e{I&Q4JoQJj{d}jf8m?C=vGvp!bRyv|6twRD*ki-@YMkZSCBMsJOvq`0 zv+Nu_l`s|d&M!K4m&J&gs(x_{OQYbfMM9U zE~N_*zS>0OibkZwi6D1CAz~KM*{BNSr=6{g36x+Sa2VR9i>owUgs)2mpTpr}XyD0&92BI+`Kx#yY$sOXuXsE7l$2;C05 zoGTZkICz>ksP%S&BAI=HEg@Z9PMHgda9kMI&pH+Vk_3gQV1&M3f(=1ms{Xl_P0*5{UstO=46;OHfoL#w=OTJ=q~jiP4V}6~2-L6^SuRu+temRbntgv5NZP zqJmeFppY2kLqO+bPj3(ui>MzprD9}U?B9~lM7x=$MgCqlP3zR8yyyo_377hST-5i^ z@mYltxzL0eOA#al>**&;$>byyi`uralUWj>6bbz-0W82qAp`&^6)|7`XKtD2o z1`vsy!t*9V4-P10wm+0Sub&d7sCcpe)||rS7D5cbJ+dqm#^yF8(bKrRy5 zWOif+A{kph3QEX3rfm_*A0)6OS=H)b~T2 z5`tZifP_=ZYEO_5>^i9_coi{9_@C93Bnlou8mEh*3njx&Y6@OOjs!tX!CSWNbWwDn zyow%4f`Yd%z|Qb|>;!!&$F5VAygjKYceTVx z5X|IPFa_|~G76w7S$@7+bO*_ zZ7FvZP43i!C_y`u5%o5-<$7xpsMbdb+LrIoYX5xvXe% zsa8=5+TG>y@-lK+k#bqlARdE z#`HZ-uDggB%a{v+6cOF5^rM#^@4q#_GNA~hQ0RsvN?pzraisk9awbP^mkrz&{yI3qoPlSsxK20nT0p#?$%f<5an<3}(-VTB+kyxba(dk*V|jW)GAf#6pg%jO*IhK0r6)y0xAze6WAtuQWCOOU-`ceg zDfG-XSe|CGhABG_p)o$j?gFwry<`njwjF|ej9w(b4AXEBd_!A-v>$$1h(*eVGonWz z6^I>*$c}BG4KJ{+EDdo$q--^mkNNkikg&QWr9Ed2|slm8G-_{3oOFj7>&-{xZ|9UMnT{J`UCs2vI~4k@brWZE#n;j*F5dDfZ#9` zfL~sh$4gfz{8ijYg zVhJ6dvxAYmtJ~bD9bi<3vo!=g75YWV#=4;mFg_-@G9%@pWNO{ihVCM!9?sSP^d6w( zZ{5}g!p;YnP5plxf7jEY9@9*+l-HBTVA#L{Qh<$k`{6 z9=29ysU%@`BB%=#ZeiyHS7xeQkTRhg@xaPsf-AFCk{~;cQ1gKei%Z9Fwhd_SHI#y) z8}fz~D|t(XT0Fx;N=_FgkH|U&;>wN_FvgZz{2x-*8T9^^>lr&wBq)XU==_!GX zuu@XCI8x{N%4oXYNAgVe$N-td1fNKm;JEIclhJfNQb%DNWJe>dl$7Od$K0Gvpzp=a z^EJWExJOiT)$Ca9+bgoWK`>dbF+F9(uw%8K?K;UuxQycrg2~E_=|C#1L}tri8zg`G zj%k-Nj5(i#y*ptl4G{TQZ22i$ek;pQ1#>%I38|ndy9_iEhN3J$1-_-1U$GUO9O z2I;t^Qs%UtPeR``5}mmb`;Muo%#GvP&j>xJ$g${(9N}-qPWZ0MD{eH-#=k*EZkDdT zkpR!h=*$fblyxgWMsAUAf+Ggb$*9bY7`p9d{fhZeFn20F5GiiS(nv$bEW$I)x)q=z zmL_F{BM=@hurR`rSOCW@>s5e?SeevWj#zk1Me1hCqV}^+1*nLHNtyBv=Upt1;9U@b zhR^a{5&;Ltq>OoVQe>-39TkOcHqn_IP0=&#n}ofIjLyDJ%)XAIo6RCMpvW>_66+=^ zI{P{?`#Oql1{D`pXl5))fSai3?CZqri|^``kmHv8(sg61a`#tILSzaC$59SB8uSGJrQCimdhQ4L+wvvPYzEP51$<<(V6chwmFV(*wvYW43H3NFXiPU4$EvLd{>Te zI0>$Q;goXILR6F?5@lk)2kc8#e>6CYHN>zv6e z1r@O>DZd`kRz4-oMuNK-XH4r;lDwYs>=9+Hr^2jqyQsK}+!%|`@NV=9V?kKVPE@tUTRplh^EIve}3 ziH~mreu06HEO$mk8%qMI5fzPj&0=&gH+-9F;G-A`t&qD6L@=-J)WbQUilkc+d=R|r z;o2?)U9*dlAZPUpswWSl>tURs@GTf6)xt;FjFq_w@v4~sW<*D`ao|{R8Vc`XAaQQC zz9@osQ$9N!0!AahGKDScP*UzYVmX}N$`p2jnb90Ig^e2(8NHmw%*a14IbBvH0o{*qB&Q@l;VC6}w}pfh3Haa^O+CLjy_0I#DhIX~?WA#*%2^bd4Xv zS40Mbk+Dut@jQeyQY*V8Yemv!eux(kmEmmryIxit2#O`rZFSTP#{^fz)gUOAOSjbl zAjZq3sb+v3F%+b)x=_t2#~yL*n2f^BxLOiLk=avgDS^nqMY>&%%%gwJ-`a;@pTf@Q z?^?_rS|B3VNYl(FBB1fs3C)b50Dj~9ugxgI$Y>}!Ln8vpMj{v*G{9Wh18XTk$cTon zm!ktv%UT2!G~5^$NR2~okY;BC;^ix=MLD(<)O@yFNzug1rIjK)f-5psFhaSgx{x3w$_cK>y5zn@dji-ol=? zKvJzi1Jor4aZ)xwdqofo1}HXJhhT6v#ROL-Ih6#BuBCFQalXU^yGqUj%WZN}h=D2V zAPii9nBd9;C8@q3g8CVP$SPmMl?h5xazO-jK|zd_6I_{~RHUHjIE;yCD<`-zK}m`$ zXoR|;Alk|au1rvpiV7mAA2Eowa)K)p6j4S2g1VrTxS(XO^6M!mqI3fEbU{Jjl?^a^ zi{IN2Oavu`eVT~Ea)K)p6j3BmOQlbtWIQIgGC>iQ5g@1=YKY155w1*7L^%Wq>NXpq zw4C6|1Vz+9fS@jUh}Uw0D-#q^1p$J(h*;&Os36BJPiff4GG zhj=b0xH3Tr#EFsuL1D3y!#wPCFU(&~y#~S-n@9;BqPuK>&dN@dK%6M4#3%HpiV3bv zPy%tHOz7Y!kjI$d$^<14rdJ9lH4**gQ(l>%h@yyEDisRpx{TmfM+ge+!*|bxZy#P- z615Q^stXIE!hDn~6Bbb&0fM@)AWlpK0X`|-3cCBmb@rMgm&A!XprZRch!e+Dgs08? z+fo-VISCFE6i2l-q`slJendaakAvTNZE+xS`BBLKTi21U0VfW-E5I)?}xW7|sM#(9of~f?g zBG4OCQD9K?Ao99+$w|1lQ%ggsi0<+!Y0kEbzGpmHLLZEflQf!&m@X%yIooJ!<7WZl zr6e>=qtO`|kz7tjbGBUmy4r3t1)+ zS=eEE$OpG4^0lSA?j-YKP0*AigIOklSR$jJ^a#YV8L><566W=aND^d3^ce|7ohrY= z<%tOug?T;0Mpu&TSOnLNr_>aJt~8cDd{?JLiAP!8ki=SPO1hpxtd*0|m=`m`#nfF! zlL+K^N>L%i%E@TV>mf4H1r$yqt27#2Qz5cSWQM(!87fI=l?duu%Zt^pry}?W7nZW& z%cUfuN>p^Eg@`H*D+eZ&p(vy$mUwEGw(m(C6{=6qMrdN>p@(g*a+VMdf4Y@-9bQ z5=SK}y1qgjl}}0MV@Oq(GftEhl-EH zLb<@OS`O5!yY}rmc6I5ZP@$>BE_4h_mPb*<$SsVU;pj{wEp0uU3+)#fm0^EnmUa?W zrS;Z%8DUkL;jrJ`(muKjLYG8XK~M)3wVMc&a&U`X=*F80;T}*_jdeK+FGyoshZWI7 zRyKT=Bo*C#4EJ;*8BuOYvK>kMm4>PDJo-j;qbWmJmp~GUiCFSC@2|XcHyLeDi?{14PPd&kwQ)yn>MT3&MFw8Zh{MfQ%PmY6BIhdv1Hz=tq zGKCE+`EeH~O%g;61Xf!+8}yq77jSPqnh%4|gm8f*nqhT0Lq$CVNNT484&1IhAuM)~ zbd5NXT^;3U66__TCpF404TVS=l5>Md!n(|ytst3zqp8@hcK4uIOeGQw&V{bbp0gmC z?0zZ|j0(0c6VKkL#xS5|cnj2%-A@IGwOa+{fV=y-%TgESQz~$bzG>aYz9Oj`O`^!y zzm%F#FAtPsUy;;-x>)y=#xRuo0wwkCQn&od$aU9_Qtg63Nxi#Yyi7}j(Ify(E2EvT z=v9FL^cHAc6kXKYxE)v15zCHNoNTEib0ofW+sE$5+;XE$V$?KRT@EQmjlp(5LWP7CL+7S?{qY z;t1-RNouKA{mHSfOdMskNGcw#UGgWXuS^_8m>gr*4{-H{KS_OM;wYl$pstIfdZC}B z-d!A*-POdr1a(~;)yw=O_3pws-TeR`6~T5;*X&^J{ys@PBb=)Ii}H?&P&{6zORIXBpM2fQgjdAnL0uQ#uKmE5sZ(BVBSe%Q)OF$Q+8lhDkp1%1 zh47}VYxUMXu`<@m&QcM-M+Yihc)NEEUzzZV*gdH0CU@7q;mg!EFS|0ySqkd9@OJGX zZmmpsMN}Wub>Z#WPuyCW@QM&WsO!SpwYT^(CD6;ROmebT(+a<9qj4)Eyge1Z2>ye5 zif6i6xYo*KRb&Eyy3RA*T9Bjt@rrB?krx2!I?r_LM~(upuGE+Dghxe^0I2Ic)2%l- z@>fKbT!^)Fq(~G-J&Nn!48R)}I^=_a)6^fMihapYhm7MaBSV z>bkmHhjQ$Y^dUhKw}@nLSdbLUnNrZ*dX$5t^dVv0;jX_7COay!2C8YT+^tJFNJ<|P zB>gTacpxc9sf(3*x1Qi5lpZ9Q`cYVkr7rn+ASw1drGM2+^aM#+!HwO4Lz2Z)KvC>? zO6RJV>IsTUIX97XooozZRAdieDRuc#Z`4yr3c&I>EKDozTcCOPB7XoRb@@>**pnm` z`MCs|zMG9tV3=|(b@@@R)RQ#3pJmISF`zEjRhK07c0Ea5mn3Swm1TR8Qh-&^B}u(y zPtw#R$+hAZTKd9DNz!wyaQ9LdKc%Ee5{)nmortso+;pa&RqDNa$|!{-or0n3P%9q# zQo3J^io^ntR3r&T?%1w<0H(W)6fxRFn!r`Q88?_ukrf=E=X_Y*8mZ%#nzr*1B+BlQ zNHM@r_4BA(D|KWmD(4YE#<53Gsqr`KIf*;Z5 zZ=+W3PycJ*#%SS<{P23{7}Fa?Lz$AehR-@!M&Ccz4b3u|m|1S6SSgoLX;lgc`Q<)9pt zLd&lBMlrC0z^?|SvgcMSzBV(5?zhw4XRw*w{nz=E2O(olxrQtLik4fgdQ}&AZ51hF zgxgllns1fEk`)?Qu}bI}PEdAAm6Bfxsx{v&h84bsg?MIe=1nG>nY>ugK8VbV3W_eQ zvJnOqEL_Q`IDvyD^GkMU;kF$c^RsYwnqBllyJ(cFp&yhGC&We5CgHxMx|V-x&g}XTsJ6Ht3HNYbIV~B-AJl_1@~fEItNn*yWkRm)}#w`kX_YEbqpOvy#ytYVvf&2Yoet@t*s#zRj; zqlT5PRB)wN*{OtKSjA-3Dd7sW^lp{dn?Cx@{HX(_5I2pY>IIW9E4U~w{C_FC6L`z6 zs!sgWdsVq12?>QD4h*jl0i^=(&i4YztI9wEq#z-IFf`yDlOi=y10e_mL>ios7~u*s z%HRMfI6cQ!oanY~6txF!`!9C;?{2$QNc&g2LFNBl=bZcAIcMME)9H3oN#3h-_St*w zHT>3Zt=-onaW;0t*sM7rj?%Kt)_gGPbm!yE&3SLun`?*w!VUar{LYEJvjQP=0;)@*j?4$5HE9!^>#FPqvgw`6tZqk;XLjpn3& z(3z5(L9;myKF@6NyBm8t2Xk3$b`n|4^+&nkO3gO1#EHlEGe!)auKXR_|Z zr{5jTwa93dt+vNKA3l>`u17m&cywN^P#gt0c`5$ z*=sr+-PzPW%l~(J<4NcTo6@NWaCXmV<@LF``O=s6AMqyPTX#Z(O}m}>z_IDgM?-=< zZqKK)X|LNHP6m@r>d(4w+K=vV)FW`M&55po{ak{JL&<}$t#T(*H;X^|hyB++i=%PX z=+v3pPo6#VNL_2hHSO6_DrMGhQhJ-?DLpHCosK4= zL$B_QXQPnw&WMJa&zqGOF)dXY>f|ct?fo`jCoVpu3X=o`LgXAkB0s6Xx?T_ z*;OVqCe`UX^Ww3NJ6{I9{#c08n$0HT%~5AIU?s-W=2VDb=elLV$Ybovn=*y-_UAq1 z*;kG?XZ^0bAT~EAy|Hd{-En6~5-HWqUTfCVd(L6p9QCK0z9jU~NC&u?6&&^GpT!5B zx~H@Jpe!d^c}=Eg7VSL`IdZ7aERRN;JtrzN%$+%NGa1nq-Oc&1JMfnAjE!Re^a1V8 z$jWfWKr6G?Kyq49)xy2{4rMB4v472*I&D=}%jBXp@a1}(cIJKh!^|fAnXYOsh#t|BEOo0tah0qa zmCe)N;wY3~-{u$9UZ3ff%Gc-g8hqC5^~1@Wk2H-kW_=T6+PlrsCg-Z}%=UVd>15uY zXM7^R*B$xf_I$vDV(~9V2nyB*n9Wq+>`Ysx)MJ3;s zpf#Ql>G_P~+zZX_3ga$MgtnksTnpK3O<0uC)Gtqvkp^Qt&jDxU)I6l+)%IqQo5zX-$bklX@C=g%}-F!Pu6qVqH>=khoGSGd#It#e$D1bk4Tp-y4(s;Yd$q#&*WV z=b}zqGpY+{sU?B=4MuZr#b7eEa^04@G-4{tWl6L{FVT&w(?R*NP<`%X<(a#2oEtG4 z3}&s7!^qt9TT?oM(}&z{dge47ay4gJSvk|>s%tee=JGXr`88KB4z%}t-C?IaB3Is6 zO>%mP&Rm&CDir8&rmJ(vaBDy)1s8)%MfBN?ws^>~rq>1>P|i}@y>Ys13k+ME@EFdvn%nj`|M!hyiPIe&&w# zcs!lbxJ_DaI3CUB+&q3tWhxm=Qa(_$yUTMTqrfN!0Ah^w%Jp%hqHflI9h5`D5KK z-@PkfYEGI$&F(}vIv+87*{zHn_LW&|B!= z&SWx&U67LynLZOYAuhelSpk+w-v&C9K?d659p0G0XlYqS@w5%nA{hLu=;TAdnT3 zb@>z}Ih!PbPMepHmP=o679PxXV=NKFV~$DHXn`!S-yPA0b`=ZgBkl|jzq}$ zX@h+)#8sa?SalVB!PP#$>}!oroW&m~d0tCED2W$w3V$ImGy7C<&; zkAj(a4TV0M%(~t2Xo6VTBSDicqzGckU{5+CZ+?Coj8ztvZi1`y6P3FvxhS`o&4oKg z2E=faDNt(aptgsz8K8lcgtpLRGY(USLGSfu-PTl`A;1_>#&C%Fq&k-jTrVG@exh<$ zB_-t~v$;S}H<3GGA1n_;G#d*v1)CfO0pd7=07$i(ljfv7=Dl#g=B@E`4q$5nfh+5h z-7Q<0OQLgEB{P*oXLA{GAG@=Ww+zR^O>tV+xfVclX_(IDY})BTCje5=sCkFq?^HX| zh}reW>;m)Gghozg)w%G|ojYbXz`GD9(bTi@jZw|-KQj`13 zs}$vRVN)Cmu0?mse1f<1H!48)!spJbKPr2aDBW&;KlGkL&&H+Syyw0UqdVpxaBxEe zv=b9o&$PFi4qD>9*ot06T!R@90R}Rg1d=Fy5PG(FeJ_c(`iY)Z-kn{;oU7I?8$A~9 z@kYFrUnG0(wS&PZP6-f!%^|dXdUQZvK`vk$iM+=(DO&B)YY@iu$6A ztrVSSuUXvl{Po9eiFP=VlMFiJoX`_p(Io6=Hk$RFWA78}G>48%hv}Pj2YT@gTcZ$& zHvMtmpYPw92H&?jjX|PUi|efQ@y|p+=;($iO#??=x--0d8q)VNbTOkoAdhoReMUlo zi_P$Nb+-b9^WpsG${r+P*C0`)>dlL*u;cYxqG(D1p5CX4cow=zP1-(t;E1%R;tQB) z2Q&m)XK3aFc9{v9`5|CrG|oV_C+5C$FUiFW66Lvbhj#Yu5!B8(6rzNXFm|Igl{^5o zY*I|%4<6cR3QKAM14eCu4lM#Rlo7IG)quN4I%-RwsLS2kx3h02+(2Ov+lWKan~D&o zV%=WTX#k$easmCM9r$I|87#;@!gL7dki)tb`)K;cN$aPm5xF-c{lz|bQpTqw{i z15B4w;ThGYl4!wIxpk@aTqK3iQ&AYiqsf_&Dg*{egX(hClgxw7S(?Cux5&`DY5 z89ULOg8fC-5znrd$8=i%16$?5{^yezhfrbZ} z&j`EX_>-McoLsD~_{ zXX()TR1(G7TR{}kZz10y@GZp(9t4aro=lyb)e!z6UIj78wosGXSa; zsl$0ClI51w=aOjI-U>D>JTjXLH9s4SCX#ldMSw0P2HB1f4wyG@O?#6bi|4KsJ{VUA zI0HoEfVwwuAj42OMZoC#ToRSL`oj5aE>{nE+k>7IPFqYOJf!S`N;M2K%i4pUBl*?p zO{6vZJTBS8mdqXumfv=*+qmtVuT^GibEzt027gTE~^(Q?dnt@XBkVN1cUcil&@)L zksay&IIgQ1(_2uUIl*9%SpkXjmgJBGqPE+k38aj1v|rM$oH*nLO2%CCOz(1o>i&^L zOEQ&C%4pIPBR@xT9cs;k=|N6n{e*8*d5G>D7o;gKGM-D6qH8$FJxGIGC-{?{=mM>! zC@RZ>pHs0$3|TUl6_s%sYh=sPkzSlgFOC5WEo!yhb9N|Vy1qLSRPs~%5+*R$O_qr- zApzT)$(YMca$U=Eiw97jN}_c8D~Mj2bC}A(EqQ-77&`-5iu2Ba=h3z0MMMV}xfVfa z!BgLC!e>Z#2eAnjfPpfk3oEOV-@Q|^MLI4dtI}VwLxnrrnPX8%mZMup)Q+SjnI+kq zzW4@yI>YkFu1z#e$%z*2hWj9UL3kZ{z)}gbqXFv6l4#xj3azV6NWMc8x=i2%(VkBQ z5S{jfpMv3q5&>+c(WY21qq$qcIM+xZoPN2-c_iK;;$>UJy4I(XDBb=Fr3-J%rZR!1 zAcTzh2r|WioQ^dt)oheDm*f}lgxa%kT_MigUdd|<`CF68kSFENYsvWH3=MGvYI2+C z+`$SesQVG7mW1-roLTwJFsE@a4nm~?-H&8L9aK^HILP2wbO_iq- zVq10=;3aio8LTMk)$k;yatJbpry`gGFjx*q^3d@>Qiy0IOBangqbWEV5;cJvO0P~WfJq{Cpk*h5gfQK{$f6vgQcv4}6coUKl za0wKxk<*5PKzimK2DBo#b=;eHCCjox;j$pvvW(DMxFqluZFcx5!okik?9mKDCzI4c zM1zq5;o(6-z$RdZZ!AN>3!IKC5HAF$wk*v=;|^A6Tn${Zxv)VpVn}fEMYy3-j%`ey zfo-uuas_i3Cj=tIds8ocIcTU=AKeHDJnxB)ch7U!_xfBCjXPMOadm^q=7M}0x&s7* zgXjozR=jeCH4{Fie-ue~r@?QEtO%-+kYLljz#5uNI-;b?Tw*E}(QPIwcd$a`YAKV= z1rz{1@A_;GjTo28Mf(oB#y4kC2K=b*163@ z=MGlrTzzR`E>|KzpxiWte$bFG(spUO$thrM_0wV?L9HSthPlJd?V_Se*7hhvFv~d0 zP2{>I%tU=v5{)}pp>gF}VkTR9InPN(2S1dnu(^p9Bs`_-7$zb9Ou`D)Hkd{jXtF2( zdGb8q|1!}&Cw#eUG8jqo_ek(n7Nx3jd4NyXb!)If>q>WL(-D70exk#u1rR3b8|IEiH$ON{qrLZqNO9VS|eZ5nBP7P-fnsl46Es=Yl? zt>S`sd!|gcU~+<&uCJ9^84jrstN?5Y3M5cAKnv9>r90y*T9BUo2ju!_P#=snGch@$ ztKm-l%Ug*q)$%9%^1@#g@ZpeyXL@8zR5hQdMneFVr4xn0Ddc`6l({1~W0DRc!VJ*D z>5y9NRNh|aD0f_;|oUZQ)yq!UVr(uP<~YRlwg3Lm)f=D{_Oy`aO9B3W3q&APW8v zI8b0Aj{%c#+?z;~vWS#u<@I&ufi~HR%=hxw7oMoa=FeDF?kG6}cOW$Y0c6ZUw=?lV zMB;M{d(3-@QjjYR>h_d&+fm3Z*Ye}lY*eMLm1srXjIxg}6rt==WDZozW!}w9>4F?2 zTr6l?(-9g>U<{~IgBd0bBuV@xfP(7LHl4*6{(OIT`SR@QlCt(`C5kX0f;jF)j1M-P zzz%qrbL0t%4(}LrCbkuC>rEf|m02IeKs*NEk%1WBf&>A0Fa@<{E1zTN5R`gs(yA&y zif_1h|BKfjx&%^b|LIVi4r;;bZsPlgBH`&%WT=l#Y~ZFCGP2ThhpyWfoVDh2sW_4K zrWWkGIUK-4UG=sSUDw=<`4Auh^N2}pz3*&KxYL!c8a6N!H&;gzQ0ZtP;pQfdn!A7f3EMan~`O#E0#G&9wtoS zXA?g4oTbUQ(fD-Yc+|})sm65&DD?5_=FsFEIbOazYs6I+yrPn&6s$`WMeO ze;mAu+tE&Rp1P#`{e>?$1-;AMw2m(F)%Pb_&+V)E`*XE-wG@9}Rvig(HsBRq2W|#Z!8=AMDcE03OsE~o z!B&W5!}8AkO`s=Pta z^s!0h#2~qvCT?KA#Q_#O5l0XeW_Q#nxrrc-f1!I5y0)Zfa{L$1q5Re;!A$!EJdCi$ z^``c_>b-zcXbl}?G7$<}+aZLa))69;xN#pHCx|GB_Z0z5v`;(Le$7n#ebwUd zfjyURi5119s>=j`{0y~HvO<&Y6o`N&#MMSug&PV3uq;35M~Ih4+Xvc3!^#Z`W4s$}fbr+v^T_BuRVRGVDX9dI zja1)Z)^wVq^7jWiRh7L?s{PdFn!Z15+rL^foWI z$;|>2$F_@A`5`b>34+gT?CBQE?_kznpDI5WK;^G5v>(5UcBg76w6Ob4R)${15(AVl z3xE|gOO645m-eHUqp(Z8B?6HDoP#LK3DhgRFapx`&$OTQFVvraKVnJnkiZt0KSM+Y zTPyG4`2ZbzQz>l7?2OdeBU}mGk$?xsA|cK|`S2m@)>j}^f6?>H;mft(p%$V7y+Yh^ zHfVOim7u$i#vo-$61d{vHspL^s2Umynvdv2hUcTWwPJnpOYh3or<1Ba+A`mO!tryU zgwxmnV>MBzL_Vz5l$}+o0V8MUolJ4KGw-z1g#$RXiX2PC`$NO3e1Dxuq$Vuc0A0j< zexdrrH%J0v=*^)-q#PfGBA#*b0a|LU2)b$*Yd)|Eb|Z>g*(9V588_XNv$q#sFN;`T z{Z#d}vWqv@6v$<|FMJI!IDm|+7dR`=S@{qZkNT!xNAwStcWk-iZiwYU9yx$4c00rm zFRgt1BlA-`eyQ$LTocQ`Xs$hk?xVq&eBXg4Mb8CUpp75{{YE4~6$oU+=0}o5ILH|h z;)6jjOX0D3qP&oOnXvlHQ{CrQuI%NPt$R5aLvX{1N70#J;t(n2Tq8C&&|;s$y&H&d z1e<_wN=N#f1y;@~>j8B>9wakux7V2 z;lzgv(BXE=l*^Bxifu{+A&YVs6?i~jDobCd8R9f2f~QO69^6+6tLF~=&6n5 z*a0))p9YWuBy}8SjG-(5w-3-i;TJP`%8xCztXXyM72#I*KCKf1xD^w~b>9s<94|OF_C6?h~(i(FF$n~$NDI*>H5Xn{$c+U zm)nu`94_mDZmI{}=8&&Op$CCX%EfJ@Lo6Hp3COSWPDUqW8uNbrNShPx$4D`V)L*fZI&pCbqJQ7YeGPpmu0$#HDwnsCjZ*>Ma|i{lIb zm_fKCQ-U#+soD{C83-1S7SI}mwwa_hXeKI7u;^%I^~u!<)KlrQL+JzxPq3YPf-EY@ zk}2WV@~ug_lTYa7uxNV4fddT=Kwf@LKp)Y}}yOU8y78WiffN;c<0_4xOC`Na-e^vJmX*mkJ_GaRg8x>k~*7 zV)Q=>SJa;-aBvF~DBwkho1fVR>S|X34jVXTa8OUwcwuM*B=h-5fdmQ!f<%RA3LdIR zK)vQ0s+n#;p$}aj7Yncj1sV97F}E5c3Qk}-#$r(21+dwoh*GHlY6)HedQe=TEPD?) z(zrvBKwj*>{Qf$ZkRO@8zfggit>hcP-~|DHCf5*U?$M0_*bwXOdIb&{)@V4!>?3qa zd7;7S?SG+N=Z2+YT7wmE{tJuF9FOH?Sqs79|U!CtBaJGm0<6iQI}6fP|n0R9>A z9hQ~sSkw=}!3afkgy0RKu}AxuITEqRu&qo)pu|j6bO23Ve}Ae3rS-D!_h%-8vTcfA z)UA%inXo?zhOoN)Bko!Rohqw%WfKRLt4hns$EZhOGSKdw&WZ$xD{BjoD#1>n1dI9{ z27WRFwQH*9V@bPUKyak05aKhXgb86d<5Jw}9n@>{(Wzst3j!q=SHLJ`0JZn0^*K_m z#R3#cu*>?W`bVpcCNyg0Z9W7R*{mZs8U;b(R6)Z8R|dsM=*TOdf{#_ngY0rMoYz4{ z5_~xUF48mNb^)p2eyRwe=lL!ao?%2?l4#To6EDpM-(L@(3ZrRI}d{?Xe-!5TaapyX+zZs zJ~O&zKx4XMIFP|sG`$JLni{A$L;b9sVA&b!rNp4jW57HGD1B4Z>=)h;4oQ6hQYEOKJ(qx`J1FYH>zWIT=Yf4Y=1@{5kLp84 z=A$!!!cs{JtQi}E>BTzPj84yAETi%qy88Q5C8)3_e}AC_Eux*I@tyUts6fS3_+ILp zM~azLdw|Adz~DtwaUhRe;DE6%9*M9Cz*m-lI$^&vNR^=4ntTGe65P^52fGa}G>^n! z69+^6Zfq{#j-GZFKyHrN0OF~y!=%q?cgqb(NDygl4F*T?{#*xc0s1u8 zA_Z7&=OiT%+BBa@X4$*K$0)u>(F`~SUYS}AED`=z_i`VCV zp>A|KQ3-&YwBTIH1w@l3zKTXF2*LtJ1y~XpOj1<(nMULbIW53MWYx<16NQjg&4A>J z_vae%kf58!!Pw;N>v#dDaNa{dhttGs(}z5BL6KlPA>^nSSOAMUCbS%{Mbyn5||u!a0I-BSvwWfh-pm9 zE8slVkK{0okO6!71PYx944Fl%9{l-m&~Xq5xej);PxKnn)(uXrILPPn4>$3VquXMi zF!EVsJ$7}X4RHV}MtPX(L=_16`-=csXr%ubz0B4`{!5=L4J-ZgbmHDc$q{ClfChz# zme#dUm7}tK^U+9boa^LVCF;0Yj}M2bO6=z<5v?ur3Ynxx#i}*Z(oS5C_{L|*M1&P28c|RHfEK_=wb}4^;y)7G?l>|ntNcQ>u%)CNOMzPq(#H6ngROkhtx_X^=II*9NJ zaIAHaLQxCPOe~NQ^%39{clR87{2=|E0Gc`$ide7|@Hot?^8T<$<^AWQqzh1Jz@nVx zQ1I*!!r;^zl>#dmBbr6-oKo;kJa82gYMnStiuY6><4~HR@@%}JxcP3^DG|8V1VCw9 zI)Oq5_6r>-U4i)oBV&gN5NMDPa!f3>W_ei~B{7O{B(n9<)77akKRQ5q)oChAKs{l{ zw@cq&=)j_I<&dIQ_6<}hDi)o{4}=Rw$MMwhr^Ea)h%}y(T#F>BWBFOp*bA6d9v9_a zQQ!sj9Z20mWh%J{<~nc-&=G1^c1Y(aBt?z}SVS{r9VpP0qrVhWsM=O>Db$E{#8}=8 z7>f&F19tOf*p$fzq$*HTvi$v-3Ou+a0$^IB5vPQ-=A=PT<`2O^xhAN%zMhM$^gntb z!0027htDLN5*5(Z@2`jERx;gyLIW0cDTf?no)0UJDF=IuWIYH>9uGB&ndc(I?01P^kWl+iznDv0G9)VN^szS*Zpl}P7T=-<6ci^N5sS2q86n z)%UNgN)r(RsAk99D-)=b1(iD`E1>q|4PV~>(1I;^jfSNdAad3{DNN2r zw7eKcZH%MHS9+G}M7d#Zif+w;B!dO8l%d5amP}F5tIDpSj9Se#<;A3PXy$WRCQD}E zuNDUZDVhg1a3m1=l^jwxvV^*)LGFVoFKwZ}XDfQCLG6^a0`{PVl{E-6SlxtF4-Q({ z`-@Zwz$2Pkh)o1td{QM7+%K`Q0=lTb#19b)ni1PTyAVA2t&m){;~oa)=t zauWpG{OgO*7%jq*A;Pi-dI$v%4tX;Q+mRSGnS@q^mC~96aYebu6jT`0DcZ89O0)X@ z?B?W>BPau%u6`$ff35=$pBr8fQjrTHxZcuShD?9&A`UTQwsYTB?3oaH2V~JPnsr zr(|Cau;UO_*1z6vLw+NDe=mQ3;RY%X`tn6$r7;~hZ!HY&tsIo(i z_53D7iQ_qx%ERWbyuTirODLr8@8|C?yg;ZwhZkD~BEbFh{UCcvo^Pu7ENjWm6cfDQ z^GN7QP=RrR;-=mdu9&^Q@PasJb@@wm;9&9kFYkX?&Xqp6CF_Hsuf$mfSSpwoO4>z; z{)=b>S1mf-@~#v`ut0PlkC|bPCX_hb)vvF6;SOy2^~3z@3l}gTADL&(bY;eMxb$xl zzDj$!U|HF%!bG+ha?2n=ube|ML3DkPFm2`CPL>~EZ?gFY0;es995?-i$ zA@(wr`j|sLDKKFM4~*X%4hfT+#ekp#ToKSu9RDfO0^L-xKfLn#+NYXNWk{y}{h7Id zkPcCP-?ac(*ul@nKPPyKA7Qh;cW57|1yp|BbOoZ(iw<5Vm&MxS&z6Nx$Wos`s`?a% z!~}5FGhh%b36B);#;xm&4mP+b3;cq=px{mf(o?k%JYsUmHo%6gs^DA=8nS3*`?Wf& zy+5rFQAAfPz*75BcF-utA1heuF%!LfHVQ`n8 zv=}-uUkrU&7gMuSwkA^KlN4>Z3okgomA-5N(`pfEuwn~}{D@YlHku*Utd6WrgA1*w zHJa!;lbQgj&XTDQIM{!~rsISto|2$~4_dg`f~)-pgh$NM5+&^IdhFr zID`;COxbv&wt>(X<@^XSam#};WKO@3QO;fn2&@S%0amjhlElid1fjHS4l-+4mB&OQ zA`iNCey4gw?nRIz?$CtEs-TXdMRqtPEQ6kz#T0NlxkH?^=t<3A z57fG%5TX0^_a_RG$CkZ6Q-@oQe*iIZwbVTc;POBQBh~{E>*+`^r#kF9A0eD`ZWzB^ z`(<}G1lgn<4+8XSFHfsSq-FDu&z0epbsnlrm50T|*UAhI$~%FGDG?%R`q)f?6ONs7 zBF8}m(U8GFZ-}G@_UbNeEU!$jY<*fhqAPIz`b-sa1>k%=K@ct+j*^I+scQjjJIpO@ z!0iz9D_kIkU~`$mK<6-=U^LM4R(b0MzxA(A96?GqfBn)C%yT2dXjd6ISp5r{urA-n z^ADaVrUn5tH3AQ`LTJzq5F(@B!-V#%yuW_EfV<`DdPw3SfB(`EjHa?P`b5A3ZP7A9 ztv$CqI=s6ELSHq6fJW`TGksh=qZ^36b$t zFel!Ps+=&z)>j4O2|FLRmf*zjjocrBSK*9QYKJ0RsIPzG2;v;&?=Q5Vom6u# z|L3JRV6q`R4j~^@PRtqonmK3~lKvgqDG&-&5MY5+qJ9vAw}i&1YpcIMQGM#0^7j{- z57x}w#Uk+9(G@k{6AkHd9-a1}@vJSIfJtOa!u4bri6#Y13rGl59N~mArbAz{|IN^R z58Wvpi3X1n&e66M)Y0N-C@J?{bb_Pr792TD=HHK%%E=rdO-kN@NrE1QOj!ATjIL@R zn3j&91jP5}r6Y&v50F!Ixsw6Vok44lVLSb^8960F$~URJ zJ@JIwsp3;R5^q=@z3vCSQd|LNp))#Ao~`OgY5{Q zUk(5egRQIUp$0A7aCu35Ev}%rIFe>cjr8MW9y2WP$ywbfK6hRG^V?l~KTzq&&MiSK zraR-;>G|9f1j9vfu9{3{7XFL7E^nn=KotQ+5Ooy-afv8!i5Nj{hFl7rFsC?a6`H_M z^N_j_q$*GWNxlb#4veGcm<5`y!6KZ8_a&;posNK0Y?gI@RIa(%fll?%_Xkjd;L!kQ zfEbw+=GAL(yyO_9Ixw!G_x(jQEV$Ev+;wcK7sWzS!yqN4lF&sv$v@FzDPzrKESyV7)iFt!T-~i46 z{{b}WPRYF>Nv1f=gL)sFpOOJ!5$da-`hLQMzt)Iv2uNR#X4 zOh|>fo*-&TFvZQl&$K<2qt%oj%+A?jrV&aU82_udr?5Rm2m;5dy*(`;k#5KZZ&^Sh z+{P1+rXX+zI#?@LEIm6-?*hgn=d3IQCXTrnB}Le42-~_ASpqq#ir*cpQ~mt3fCS1_ zOdwZ(ThgqNZ$!jEIG}29l{I@;u*Jy0=A|Q?1ol~{65%K@bON2s|Y{j4;Cc8mR72 z+7j$N4ypAiIujN$2r#QpAXR>NUHJqG<)=lMc7$=yi&AW)R2>JABH=Dg70n|^JKP6d zD2R!)AJ;SThDkWpK6h81B$AVEm60|+aPvC z$si0vfWr`D$-$dACUJWuqc07?>oLQK&i%fOu^z~?ypP>d01^i@EgE4{v-fL!oq>VW zpZ!!39i;*!D43SQTP?@34h52f0QykOvQTi6IZVn;CS;LmmOe z^#w?kAhneXK&Ax0{ua*Bvu975oIL*IGbfg}`w8=9KIMdUKNA24JkKynRq_tBW|KCP ziIWF$rK8+1ouD_So<6*#IL4KtTI#c|7Sc)*v3)VALNQ`&kuX?=1XSF;#uIk#KyXY3 z@z-HTGaa@7NWf*Jxt+%d(;y}swMr$4o^thLnO+s+a=KyyORrE~8ZB9f4UK{M*nRP( z^h8`YrkN{>lp?ptVo*|O5~#CyYl=9qR1g@-Of4{D9V70giV^2K-h^mHZ%kDyOSUk!0=rK?3&dQ>%z>8&sVlbS#!jvo zm!%|hAhsHuiR`n6+<(Ckdh`SYj!Dh@#C2pANtYElLB6Yhjh0_vBW`eY2kHfleCWh6 zRYH>Oz_OGC^Ntf9b-UaGHH6pz`0EUi)z?H#vQj4#88WUCbOHe$bu6;yF2a<;ot7}_ zkiX<)rqQudl9+&N__F922EflzT#b+GeO$QWP-X!xLg4*$dXh-xxmrC;Ee z^4-wq^s9tR`o~@G%=@!K$1*~m7LlkdDc)arhf=@rKmNEYv4Wp12G;;m5v3fB+<4$* zE_9AU5)}WqdM!9=ln{TKu`D&V@cw#vGeTFo|Ak^)UgLtK6t_Oub|Fz@#)!43PniTx zZ?w0PLvgUhNT4AICO?tR1d-B8(1em{GJzyGO|NkgQxyxa1P7Ju#`S_wf#_)wg(N&t zwf62jleJdf1gDcRjB0PiT3T#?2?HTf$3k^VtLadOsuqqjJpt7`H^#s&w7-T-uEhv;=aZAe< zDyl}v_-P^#0S5a*y`#fHf}(K?wl>DR*hl!Fskg!=QKMo*J_DFwR07oe?&BM?@IKdSN{hUXe8C0yE^E2@K1Ixq6Q z%N7G(kNRB`fK&yl9mxb>Swn&@zbOK60jdfG%`CK+kg-+5ATD5W=_Y=&7OhiUSv(eE zC@=wxLnWdbzvP{pKmre^H6%idYy!&~67&}-YG#Mp#lS(tgw!+t98_UBSRy)(@d}|7 zN(NlmqVE=I1rBJg#DgxM08I1R0;Dx02tUOFWIFKR)iBmTp5aiT=rkc$%0K|2lW}bv zI&-w12o~pNn;-QYDdjl%L&@_FPc>SvlpI8B5RO0vBuL9hbT}{OP=JIu+AIxdh;fe| zik>QD%lt23j3v{8K~ZCLmB*oW(j%Dks@Evg^W=TEay%*?PfTqK^;|sTiJz#vN%Y?WQ8R81PVo{ zu>ib7p;qv+1ff!7-X&oq6X~PXtOQ38cZ(K;Cqbqh8{UF$4`@SW9~sd+ywU0wq+zl` zl6(S7MTj3_F_ni%8}kVRm1hu<#GHM_^vbHId@K>R0w6yPHLqX^vxtAh1y7 zE#T|cCy<88N=fnw6Z<_ccEB@ma1#Tdt1&0=2*3yp_f z%7V(0#!XpLDdbk~Ko=7zbRgnMw9OA13~&fU z508xt1@$xK5i(1>UTQFlNl^Km7Wy!HV8~x+L)|H_Krra42QaN1k%KEHQ0PDhTW)&B zk5op;orOhc9~&3xX(k$%&M4vJd9jUn5y2DOhqvxd;|I zkkUc)lX8sqO-d)=6aGgO==o5gXzoHO%1u+uHo#SkbYt|kMIP6csv?4X$@&CR9f;_a zPaxNUTi%8k$nr4y&Ve#gaeoxGiU(lW3d)#ehElQ&UrC}hs$B87HRX)cQT9ckob~so zDiGB@e}AC@Ev>*R8eC(ENX|)-xZJ^cz!%g2U85oJU))vd8WPPUjPs&ga`RE`8~+|`NFrIK0lh;d%v^v(*ZOx#t5 zO`Qj%SwKt#l7KWV9f8$mxnk!xL#ut6i`PUj)q-k9vISVyj$jcxZel5!aS=^`W1>zS1r!k|YKU6S z3^!6tA{s>6g=}j95nf|RL^gpZJdK}p}-1Y>|>si(UzF&m`=qir==tyx@~0Qp>|Zmkx*~3fyvwj?c*~XLp51lmsA&{}lB@$j+1)|F|G6Wx!cnxm@!N z{c94O^b4iv&ul;Nz*MXfMK*~U;%Xp}Wy$0CV6J);8%xoVg*J>t`czeg7G#hL9rI)X zcc5DnsK zNw*nLEcKKyE(|G|v{u~QQYLabp>>4Drlb=nbfS`yOaws0P;t&MN|I=lf4~(9HnB=- zw+Sj)h#Mnj+&1YeRsCEDQjF~%CD@wemRA64vAzYVQdC2dAIU-~+WP1r4;-W%;G|MB zQBfP|LvA1i7#U2yT5toxP;tk^#@=I7n6hSN0@)!ffiyNWU4cR=E^jvBlf!6nlGKeV z7@=B?ii!Tpf+f+iWneFnHDs5?>I|a}!TTxV*RoF(bZGVp2LjF5`^*V>IC9`vD~-lwnv9fe<{Nfl5E>GJabhIBoJPN+=FN zbpg^!60GrD0{xjOA=WjVez-_vDKTmA2%v#cRMhC35fS_ZLb~>&i?5qQ9R6wh$PFPb9|;6DYJ`aRJGpXd!0-cx1tubQcV{=k&)V zmZEYNDoECD^-<^@`3b>H)O5t2=Rqb=nUrziFS zVjDrukOL%cp`N>{$>l6W1FBnt)-P2*36h=OTbPxD+zvcFcuaI&9VZk+Br7n?Zg}EK z-E{WY>@iPy%(bVEo;f+4ZJ>bW$8rcO<0S$wBZDS9qKb5c3=X46j=LVQnj2Zr50$rJ zGP9*|3j;(`o^@LG)-?>TuSlvFfsNUU1n4NOen`(Je8_0?4VMEQS@5_E!~cb|2&3Vw zN8JZ(5xolOC2s!+5(yrt-V3F)rWL6p22OOkB86Vei%hO0f&mF~K&`b3Zb&L>ZCqIl zNJc8L?*OwX{*dBCxxsAHxDVXSN{!~bU75YT-jJNDmcG5viUPgt^X<9JiIh;lX2M`F z4M<2Ln?i(U+6M_NtyvYc(3x<%?1oY~Ok6KYta2u!qhnPqrzIx*>|*^3wTPW2AEouJ zi-jV6;Jc^NWF zn*X3drxH*o#k|1e;1->mv6%AGAzTugFj`(Blk&jhN=xxMjxW>@rs-xi7_TB&@r>UT zah1#xIjVntsuR_hpkGa;2&4(Cl>wDl5F~`s?rFOc z(0beqC66X~v&-wZ{Ph}NAWZuGg-TRglAQpg4qgdLjKz(X%OVj=FKwguhm*$wM|X!H zy<_!g*CxfuPvWDC>rsxn*#caZt3-#Wz5t0zq@&Vn3H`@>Hojk3rIW`0g%3fk0VY{r zcJJdT0_(X1LmB-HSl4<%7c|Ldyey46=DCGf&ZZ7w%Tv~uL-pFK*%Zo=Eo6{_;DFBu zFtz&;C*%G^l0=a=%@w^^V&8A@B z=!uHi<_N~sqHzX+DgtQLR!B(^R8bB{uhF{-H6J_0nI4EZ70-&ga&WO&8VTy!WYPi@ zEpJv$rf?^vDV5Z~@^s(e5bKN+94!6uz-c`kO&#p`F8DHjhm+^>Tpk^VPcR|u$tmH> z$<*m!@`UL=t+@P7b}g40G^kDK9y~YIcrv_W9sHtezat9iokT1m zE&66$J*rtq?9*~K^}--DzH~M#uD??ipU+0b2nGgiGZRs-&4spSzC3OcQyL`n!`yYa z@HKe;dK-j$g()0&)*?1mW>YWPlT=D)v*H3gj!ib3Em?1@9hjp_8+;miR9y2W1*nQ4 z=&8h788eKI20|y)m{n#}uP0d>`{d##yt(Dlgn220KlF7vnH4wS@h0=7u^{rlZr_mx zvLBHO@-q!|w0Yr)!VTG4)bcSJu|?6IJ34ScY21jw=$DtqX-Z@`(YErgt7JG=z1MKd zo{O|jy~L-xy$1%uwd3ZA#sQQLaKLWtk5doQmR#2t63-ekB#IN#NioGO5$@&8!Q*_l zsI9s?n3lOvZYyR}+?TQy=o6|vqNUb{{IY0Lhx!+-BBiZ8Uyy`riGk_;v|_ANaF9jV z*l4AzbHksmM{H@$izly`%pxvNIfPBC@|Yn~1Ly!Nw$Ou-I#KKkBLY$c&Cxw(;tD!C zu(T-u4-k=BLIo~qV%PE{3zKT%<|<8Gl*5GDGmW6P%Jjr7T6lO!`4n`P`4(DI)EdU= zQs~HQ2PBxMD1mNqtTL0m+@u6bNXublFITLK8kx*~YgFZYQ@MD@K|sa+04^$+m)-z+ zN;`Ag_+_GK5Kj~-xIx#3Fd(8U(fO|KW1;H)TY9ew5N*|L3QZivknn-%VMxolNldK( zCMGS2c7kuC(P4Bnk7g+mjcaYB<6hi0C)}4Q%!BM=Z9tE;$yo!Y($GDl2!a{6NDChzDnq4>LcuU$#uj#uVrS8h?GXy3p-~hKIk=9NP z%})J{+ZLmKChA@@LFvo;aPOl>6mirf1lou%5?vjlTSXXa0GXtPl2%De1sB ztEWSX}aJuLk+9bol~V1sIs7#waZIt|MT^-6DN2#lkoZ$Dqyd>sL`l(VB3qwL z>hiW$DO!+2HXB?gN0YY@VK}S+j|f--OOkI7096@)mN?!|_u+oUt@2V;0M4jO5zSR* zlK|@Joi0l3R;^8;X#4z?xUb0Zl;P6En)FJyI$cbF-n}>}S$T-$UUZV8gJc?MTt)I( zGwaH1>I6i;1$Gq5_Akm%Zs zTigh3ET%&~;mzv1${_*FwvM-_x4ZxhR;^E=d*cSh4EhxtsnB7XgR(xgSFW4oQ`#V@ zCLXV-k_<^o>$EX-TMx~|S+01QNh=rLV!A%7bg!D8Sf4G3J`Sp~6b1cS>2gvmkSqfy zH?Bc|y^AAJ6g2r8$L+7UodN;#^hrrlmZJ&{i!?p^4ovqL^5w!>x+} zxWHsFqQ)pevQ#o8>U=05COevoP=3)O+NBgY4Wb8BMD!L&9r*La2O1J?S_}Qkb0RghMEN#b444%F&u2Tt@ob%0=;w5(IocE?;)2 za`eFmB?>21#qCw9xSf;SBS;Gj3Z{TepsrIJtUyFqad})kauiFwDZ)%*d`ET{+177J zH_B~xGv}q)CV+BnWzzB=#Elg)qb4W>_z(-5H6G@%b>)&dD#2)hQvyuQMa^Gavxi%+ zLWfMz>mXC29_a<=t8$!pIQ7}2s<^#M6)OmZSo-LH9%k z?-s4s{@@1VxgcNiA-WEih`gX2E!QS7Q|WawTD`7Xn@klSyi(Xf2Zf#sClL-QnCM^;&I>W%Sbb6${C!_LlQpH|SRXP|(o^6wz z5x>*Ku9=0ii$Nq@kPo1T2%ynGg@*})p#3RiIeDp3rNuEjE_f%;{VZpbK>cZ@kR;8j zZ7TdQ zHEG$9kbTu`3fzIKr^`8jo0&EfPM}vfIZYJVadhH!??R7b1xwU}1dBL;Ki;rpm564% zS(!~no-Wf9((7m-*DGeTtSCaHhEK(PY*C~|2SfkOOMPpA|5=($Ef?#q4<`D4+#M86 zIXF9#KspdqW)qBxiW*KUiew#D&87f>!^zceoR?2}qn0BsY>ZnVWX$ktc<6j9E*^sb zuW?_9_fdqw^gW)>LjZ_>nYLbfoSJ zfg=2KS$wQ_VU%0D5mDp%XqF8XVQWvf5Mk_-+QOuzMi7Nn3sY!ey@1tP(J@g@7m*~O zg#)g}EQ(~sRf4AoqJ(b2MFgJvO%Nm)IC?@*5GKXxh4>~aBbannORUPvpExFD;R zC-;fb-r{<3_*9VW1#Os3I7af%Q`8?Ga_|k*3UPB-C3l{7vGGMQ96!~fL0eH1QtTDq zxxPB7Chn}##7dPi-BLE2Xy2h>r8jDq?G-ZMO4mb%9cf3Lp~k!k%BJ{k8douK zBox}Bf<&!d1+$_O>a$7R;m#^mTof-I0$*xip?L)6Q&f&oEdiDXq$lV_2{cK!ZD>9q z3YPh#jMcTUPnHN*ucC@YsP);T5O8OeDpt}IYqP~xI#;wUlK|co*@aS;*8s$-s379n z-sx{FMpse`NLO~lVmRi?yefD-l&S9YrIk!jtrar7Q`dy8flD1Z8*ZPCpziP`;*K88 z&`A$>nFky_=Au0|jf7H$W2XyP)I63AxYC#U%A~+VcarAjZ@!ZwEsZHetMmvc7h!_5_3wGRZ1Ux28YNxG>IlP&kdk8E*zo~HFpGZ!K7Q& z*(9{9v?_{8UbQxbB9<10R!O5PiSbV=gJhqg3Jqcv1@w5@Y`69b!HD6&E6;&ONEkwh zaTlwzp|`8PO?uZ3mwMG~3Pp?8yt%x7;Uuh{i4AZ#6S=z z-gABBFaqC-2~XK4>CHQQq*b#id}1BcG^_Ku7}A1mG%!ac=q64S$e!Jdjt_igcY;bA z#&yBYI6JD^9A&za{bIf9Ym+MC?kYvhW6R_wx>*SAGslnVR58Oc^QfZdp3+hjO;lE< z3Vf6m^+04*Q|5s~bYw3}F&a;OHYqaETcwGM%Bn;B6x6xssie<HcH*oP&~{;DuV;)#KLh@Aq3QqnH7z}a@Q|dfVHJbtF8pCD}=bm zZG2v#j-^ZOOY{qpI^}Oghd$OEw^{tnLDjSpp59^I5m*AKfI!Zo9@2f^cng(7u6;#) zMyY4qTcwT#(3v2^kAioPTHNLg2f(H|4W1oh54EUB6}Xq>nc>@F9f*^hm>y#4q@^CJ z-j;MpeKx5&?yXYCAm?m0nw79bk;5Sf*p+&LshURf3nDTqQZ&1F5i{IK$Qrkvs2b&L znRqZ1wWuz^=$enzXOsHHy;bU1)mAne1Ow+5zgBBAz5WH`f$Kw(IOHN+H(mxrfD7u* zP5A~bhLmb*LyM6Z-S~3f@3M^H6B(nJ%}ZXpz44^R=k{#x-E4g3qP@i8`HKTrUwGyA zgP+>?!rsOEpLt9-TtaO8h^F7frzA@ zZMb;Fk6rk2kN6&nH<1H8M zGtC$G7Jv4oOCGoQ#L339x3BxI#?PDVWqTgA_pcZNKr|jn}U4{NsD}{Ok`ju3cYz;q8qJw!iMfji1{WFL(*s&!NWS z7Vm#o<3G{(=tUR!g_o*UxbI6BykzmR|908F?cOgo{%p^^ zzxT@r7O($}eZ%cHKdEt7wy1x8@dN$t%WgY*VsvbA=~EkbZcm@qc=vjBWj}s#to*m! zd(+R|w75G~`^p;{zqY=!x__Gec(nM`+TMq4|Kp1r>$?m4hU`b<#V3FM(uZ$<`Hse( zudt@aFJAYS#evs8@TH62JFxeH?PtBF@iXhy#eHw~yy@b;$7`(q`QwfK+pX_ze8zN> zwf$uFo3q6y-_>Ytf9<;)|Lyz>`k4#j^X7}2KGyig?FW6V@i%_8SjtajPq}Sz;F60T zz1{dFJG5dAzj#Uf{o5Cx`p5;n#i?PVvHjF58o#+#UBh3`e(C7qrk7lNVEfTW8h^I7 zvwnY@{pjV3JpjR$WZ{GP@inrpIvpU!^s#Nwu(ZajbcmiIJ1 zwsu~L{PRXEz$X`<{lUid+fV;^;}`sDv4Hd$+|i_6DJopJ$CPP zi#uP@cu?)A<|pse;!`(Wd@vWr>QVoh?C-x~aiDkUb607JH)cOSy*T`njTddN{X*km z>nnEj7qVYEv)KP*jTbFG_y?Dc7pFc*?2rCfW3g}N)86pF`0BHZ=HFZ}TD=NH}71$qOoTjdgj5~U-$CHf8BR}fw?^U3$I#y;Itk7rx!NXXr@9T z9?pJr*W$q8izkcEKb6k<;Efl*JYVnEKeO@rUDf)&>^EP%_~g}>V)XdU?LQqh4)~I? zYCfL*(zh<|`$(g+{aZiRxM}Z-MgLItORrhn_nt;~`_n(t7&dm6`i=`@rCz%|`k}^8 zt^MCG@T=D2uf1;Zit8`DCZF4%yruEj#)?&barT0{7xzsYw{HK%s~Qh)RM+O+l?RGw_+*Zn*IDu z+pqcI# zcQ_rG)Tsqek0xBZj1 zHlBUq&Z<2u`_XqT-teNmFWCOW>lz0y+*z7p+*dugxC!uEl}78{f2j z*SW@JdrA6PU$)cES{8^6EtiHoZ%cSm+Ue`xWBTQ3~P&hOv; z__sH1zIer=t!GdA;NredUv~N83#Z7)oo5^0adCC!zK|)(4=wI_Q{!RV&zUwpdGYy| z?^m+l{qVg9e(Bla>|C(@)>|5CCcw^(&FIlm;f0aGtV~czK_xiIIuYWPG{&i>KNtJ-$kF#I;c;@*n z9)7zoyLr<1_$B9G;UCTZ!jCWRdD?{!%Z%^#*3FGiU9z*pzr6Nfvi1|FPM$eCJALNK zFhD3vckkn4k+*;7>c&ei*%95Z&lc<_@4e@LKBeaPKlsuR*q@5O+*|Cq_QGjyAm4ap zgMl@ znH~RySekqO_|i$P`|tko#vA;V!m<6rB|D*yy|4*E$3gnpU8go6N^uNu5n|&WscW_w%^=t+(o9#$LlZF zE;Hd@S=Lob$t~__?|J;tB8Ob-FF!ZE`pl6l z9&>P)Gkd-y+Riht_qd=3rO!Nk+s-qeQGMnr1eUjT^ZFCAX~rV~9r-hN^5!wk!*?zp zIXF{&knJpc)>%y(IZ`Eo~3`PUp~HiXO@GL)km(vLfwb;xBGWyX*ILn z2lYqp&hn1RBUh)E7B~I<{(P3#$;yCE()}4v6X6)L&d^TqvNz5MRB0-JPq z##is`_+U_d;wogZyV%p-v-92fk{Rw_`|fLYm$FlR?GAbuYxlG2btv_;S zVUJW#(&~gn7Y-XEOVtfaNNn4{gZbfkKg&V$mI&XSTn*LNmDI@&!;N2+IOHP&7} zOW5iX4J#hGyO`CpbUv_r=gXgg6N2QhVuP;PIZH>XXX$*9clntz()l#2JG6U(j#N+3 z`GD)4XI{p(Y4ubXjxz4Nk@--6viPePHy*us#@&tWs@w6o%)I{U;-;6bKkC-i2YY@^ zv3&ExgQ_f^r~YT9+IYcv)W&?dke*%@%k$Lp+|Q>M%HGqf0(zeMoRv?9=dVBaf-^s44xS+UY;-p{8OVllh=Ow|aqR`~#}*8O|>QiXYX)gGLus^oq? zy*Q4ZUOkTIsS>%LPcPQp)2qkvJXIg}^Xa?mUOkSjRjIjF@BTe~c^u8XdK}MFk#Rqt zzPs+#!`WKpg0}|u>*>?w;WYQ^;XF^t#Ql8w?%b~?S*=Au=P5h5e{)}&&e_#9(|MjUg8TXOoprC7&hwN7+|Q@)u6y;Y zo`>jv|DL{kR%@p7Jk0(3`Se2GMfFwvejXgmlEfFvOJ(BTvh6;8R_MC zK=)Gx@hcv=yTVmXem+|Hj-P#%Qf3`f(img1bYo4ks=v$3@CQ6#-*XqA{LhzueEX|^ zqw(`=ix>WS5@gIyoGXB{3 zkH)VVziRx7@d@K6j30l%1Mc4QasTi!+8+RM8GhS=F#`sp_)y7@MtBgC1R~qLGtGwroaoTu= zamqMp+3)j^2l$HtaIft%5LMP1#)SqvdhH_PVgus5_8{X@<1*vH#(v`=##b2+H6CVs zwefJ{pmDkJB;(1(rqMK7M%(BZUE}Va|LGe8Lw)MnQ;eq?I`pnxVO(i!880zjYP`(& z7Gq?LjfpWeX2#sO&A8n-YP{UI!#HLfH%=J7dd=6bS%o#Larc^KS+hKAmTAp$ty#7; z%eQ73*DU8+td8Yfv&?Ijd(DciS^hQKux2~fY|EPMS+h-RwrkC{t=Yac+qh;s*KF&W z?On6YYi~8a*Z7d}VdEqAf9;3;!;ct0YW$e-QR8FA$BiF1e!}>K@k!$+jh`}p+V~mc zXN})B{WBji1d&Xyt-#7li_(S908voAt_r`xP{wTiYkB$Fm{E6`e<38hm z8GmE^f5zV$e`ox?@xP7#V|>y0lJO75KN|mJeE9(nSSL>FdyF;XtBr>nUt@f&@pZ=6 z8;>v^X*|lf`_cYq!#H3(#`p%~vBozVk24-`Ji&OHafNZEv1J@G4jWe)R~y$D*BVbZ zt~0JTo?$%Gc$RU4am0AGF*YW~)c&u}{KMS1&A8nlIO{Jr?l6uS$Bh#P!C5Cb>jY<= z;H;CIb#k-*7QeWZ_#ejqH2%`~ zE90+?&l_ZCo$RcWoprLaPIlJG&idaOWM}<<8~^7457>Lau+@8Q_1?Q5>wmt{u-AL- z_1-5K-(-BV@kHaGak=p%Vjq7G7^hw=#?$O(BKf7`GG|pe`1+sho z(j!URPm3%=wl$+6MV;|DfkJ8sNY>Et~7#G7wFdgAD9qvOR(OFQVc;#jP2C?x}nw_Y`K_2le~ z)ykK7#SE6xbD)d`UU&4wMm*y9==3>Db@T0`X}U+6S$XXvo>YPPVvX|2-+J=&vFS!W z`Cohg&g|r;HW$~r8hg|ZA_~;{}6C1bQesbe_w-}uHN`EmEt4ACxBX!Nr#xCom&igZlg3AsF|y~JK1v8?-gEl4nM)<=o2RrX*6wL#W;IwQ#QBV zp3SwihmW_R*E&kaPmRu;IeOx@jc3pBTB(cDlD2jf+JQ3Ul^r{KdG*N?^V26!oXyrE znNNE$x?#^F50nzlAyUtsojG|d6M#@4&yprh{$eNli;pTPwwuq6PCGeNR4AC6ZD+0y zZ{8K3R+4v}m1qeieRt&O>Ct2NQ>RX! zWLIW&`EG?EKI(BL$oE;Z6Q}&<(Tx{TfOk-Y%fDKvw~Ka{XR$#SKB|lo9XWaS=qqQ1 zQlP=lB)i`ZA$-&mOB(T-*_l%_XK6?DuR4A54j=WR(Frnn=3KUR<+r}{MHW~ z+4HDxEF&||ot-;j&IdC^$^wKWWeTaj*;TsGt*;buq8e{*6*l08IF}dCz(U81Rqm|Ri1I?_M_9$#`BJy zWe2FT%o-(HqrD?|2g>-#b6z<+9kyrVg(uIQ-nilD@uO!```6CYoYpG4_V4gHr|rbq zqZ5aAa`N=_%z=%YC%2zGdCUTowj^ z?zYigqmAdDbnf%dEUm74Yh!gEQ7!{tnwMvXC&E-N?)m%uhpyR`|4ssMm()X z?(CIp43&68n3HGtb5AigICe zrc4iRJcrY?^Y>4lJ9Z%Vqa2d6ltN~&uDWY<$GN*k*@PHQ2J_QP&ofwCCiT>Ek#o&) zxMgiQE{M&UW?-nE;hEQ)dxUeRY{ZbMx%P_~eOK z+mzFzgBw?$J{N0pU`H8p8~vxVXX4K=z`5Mhz5Iku z_Jk`+j>C0Mm3Q89l6mqEWYt!jTCT$?`KupyRq!#bCzm{krLNgMMN7ltE1y1_9is{| zk$m~irs(xhPYIOtPnl2?Zb+eJZy}z`80Y#?xLb615oFmsehVX-x%ON6p?hBGeF=x6 z{JzpTy!!NPb}Dq2x1By&?Ap!rJrnu-qZ9TfTai)e(MgWB{OFSXNW4!`@aWXW^+#FJ z6C1*s5Re;2@_8auA2}m%C9L!b-6TOH#%N~2uF_Q{_NFE^cmJNJIQzK z&cC<$mA0aE3U4`mj<*sDrXt<1JbEmbZL4&e>bo;@+n#YI%!ZRtXwn->FHC3_SGd}Jd z1wgGH&!y<@(tFxpVX6A1lNvKVLOf3ZJLUxS7z2?xiHF5l7EA<5o~}7Px-%T@(dnfa z=g>yH~y`G>Ot-zctRp#^JMPDa->K*PfY-PR%w1 zD93Znd;7VwBIgtI2q%pHnF-uWOYiwg5k$Xq{&S@gXQsSi%UJoy=nhf-_0-&vldsHV z@7B^gzLFZ~mn`j(87KMw=j_V^tEjI3e<2|^5J(8%u9&ER3rpTh@)q_G_C16hMP8Bz z1VZ)*amU@ZE*SNql?rv=si_gvrE;?1yIx48!)2}dSSZWWp6Un|V!fAoN%}#ra7Kin0JV4-l3)g z5i~s<*>nR;cNSi^vGlyoaqa@jA83O%d0`$Qu6cyzE$GrjqGxw>H*U1ug7+$%J-E3O zrJ%OWYI7M6a}sgQNz`pZ9QKpehAs3w@&L`89(9%i^s3c zY(RkcfO#MVq4jrWOL}WhS!s3YvZj_EWR6fws3qbke&&WWf|sdfu7Z$F%PEITqMDM# z!~9A@^DAB|0AoU;#ja6VIFzLZewp77or@gT7!UIn3C&yBupBAej8rom2C`>(CQ9h& zMQClBg_sLoOXcUhqOZ^%6y`1xy1VE|_t>zVv2NH8nE_|XvNcVQhq;M_<|bxft;2j% zY-g{hb*4+7>H=?wp8=cLZf~vj9${W1p?M9cQzIOZ3ZH3;uw)=RQx9OnRS*^XymPb% zgn5L7<`I?xMQGa6?IhKub0Q)J4mafrj*VOqD6L7Imo`l26uIZ)l86>fB*L6RLURgB(+GYVHcc(V+cJ7Us=g?_RiQM? zybqKJa|!AIHg))#4!4hiBD8EtH94otWh`zk?&UhG zwV{Vuds4Udmh)123gkVI1L!eoRb#!`iYwr_g_({$1UB{^TeDzEUd;KV)uESyGp480UF_mQ;&#*geN;e}e zV9d+;>?@mE8pqZF59sQm1+WH57AjW2v^zUnw{|+3ER%;z;#;-X408!d%_S%&4P8^v z$C%Rjsg9-|WZOL9oX9&PL6)7y%x>@MNTbY>5y~dQTtrfH5$?xrG z;P_xE3sR_;*wa?mhKL0L1V@3q4r-x)GR%KO^rOcXrg{)g!5EZRLZDTb+LnSZZ<`o!Jv?kfPjZ7UZ8J&l?^97muSIM!OVI{--2M)sUUL;bE5Y#E9u@gyA=nogQ zaidcmaf(%#x;Z^aM_Q-`$v#p`X_8?M1%2%yzoY!n>ZITBU=1gE{R{uz0{vlGXIS5h#MzF@t zpmcJkn_+kf@KRLld7iwO7hTiHH|QG!H535nx_Yld4_KLMA{a?6DoV@PYFL+9veWC(YE4#)0>PKV}u4su9Toz zP|E8_7RhORtxkD_(TI12L)2BOabg#(R6+ag$=i~SlvMh0Llj@w1~#A zJg&*wlE0)Q-3;{EK{Be_S{qW$J#C#pY3Tzxk}%rE8z?7gQec4o*%)CTq1Sn`7OHrJ zj0pj41(eMLG`^BUuNWWE`4tR?IfZKN_dqD{u?bS-HN=oa_3qITopM1h#4ygx9=x7{ zWtXN2Qpy|$kuD}jG<$I{C_8a*zJskCv#@HPPpYACXu`SuBU03iDG{BUF?Y)r;O?Hk z=Q(HZi~j{6gRw`j4N&^(=^~iHuO*78F+vZR?L}5|iZ;SmN7=b;gxw8WdQf!CFq4RD zCg`87nTZxoG$39<5kd*FE2locs%eL!beuF^r*zn10ey}o9mrT3Ffh)%=r7ZejzKYe z7Ns~HCymv&Xeq5%<4|*EFOJpQ5bPl*$`Hcpf6_Re-{FL2_?~UeD5co6mZl9TaB_iI zF)8#nVtqdeElNEvqCtgrp+jXAIrx1r9A zyq@arrQaw9q zk>d}SR2wqM9MJht7n#}wm;nQFuo@Kq6t{y0shl*Ml^57yD{a`~q0>Z26PzNb=Y{aC zf$sunaw@A^2~H_(?N&v9FF(L8=+Gx=F(f^yZd+?BR}WD1X|NqDeKx{ON@s2bIspP( z85nvwFVgK$+P2h2Ru78*7NTy{K8 zBL)xHqR#noW{L^}q?G*O^xvozae^KK z+F%{oa}BtjDw;&L*?{$j;v@_s#bh-v*VGmqj{<})MnuFTSQF?m zPywjI`KcaM+z{w>Q1#1YkZU%kcuXfnbsiI|3NM-SQ%z~Cp7ers?iy}qVLUF)wp=1p z!Q_a3VuF%}doM+-qp%TeUNcYw@R2n+qTW=bER_bsR7U_BsO3Q0)R4(EoaJ9r z5D<@OwTtTweMsG4oN4$)8xa^|Eb$0r&qKcNLRPvsWe3ysUOu{-0{sLGgSe5N0nRnA z=o~|<@(PA)r&RtG22>;(XhLu4<3hKr%}(KjMBC{$GY1!@8Ue@fH0mQ&tItH8e&i|% z`R}gu#-1^y(ekl2A4mZi3TB&;CQ!qls#m!T)JYM&r4J2gVK*(VL|dB+4n7jJ>8(x8 zb~Ze(wTD7NXT9`WUKKAwGjSM;r#3`0Q#Lho1D1j=4rly-B-R-1Y1u&B0_BY|WmAfl zjA@p_qt)0f4u4L4vzb_#q4~yGwX`LaUKELGD~?itZLmZTGZ9d#B@{D4&K(RtQA?CU zsYf`uF6aY6ml#zp^u zPBvFVOYUN!$(_zvqPJDRK8GOo9twwcNiN>l7UNZjlc9VhoLu4QtJ(`<<9q-%IvU4< zI!n_;QIGvdHV2Q~kc@?fu{tTqd4-Nn#lPdIL4BpADQv>w@XLiiH5(75BH_qk?+xe? z9`*z13{f(srfw7J6wX}Xd&~tGO~5to2A3G0jbBR3=tFr&II+=tA|}Y&0R&ou@>1-I zo!U1G*R(4h3hU?$Bzhh2l4*xUCx-1nH~wf1!PU#tL0{&zNVC~ck`c~3^4@|T6opwj z$S;M0U9?Hi*)Kwq*o~QjYTHSi{z9R?L8lz4*}BB3u~hm4KHepB8~ z<*i!E6c2R{I^~F7$TfYX2R467xhH1`Kwt6osn((ETd4W#?4$YEN~NM`c6z`uxzeEr z2yS`2qQjeCRtas%jEDLGor5$Ngdoa{vHgbVzO#TH;V)|YDb{37{al!XAEv8CDB7d* zk(3rFOaQuoEd*`IMB&ykyP1wO!-zsXgHB4avm{y%>~P5OHuz4e1i`}Rd+UBE6A2Ar zJl&pwAQrhkM-Ob5S`@Tc6Brsu=v5NZtyw@AfzG(WC&oz|2>j7t!cAAt#5rl+m~?Ck z7)KkBQQnh6)T<1%CZWP}96#*|;4yU2Rv(3lAdhVCP9y9$0&U!d5H_PCl28HqM4cW4 z7{i@wU~S-Lc49*VW0gIn^IDr))K^zAby-GbBcUSm@j4}FZU>YFs4vmh#*{9B@*vhH zS4_bp)go-as|Dl<6_6jN6MZl;&~9jg9n?Wf&k}C9jjo_Rw8t%ZBWt7rph_h9EqTME zlMoo*cwYE@>eO>$C! zn>e4=dr2e-_}WciMXMnIV1T)XZN`$WhL@w;sV9&|H3tbc0aw#o z8+))c)^vB3GGSm*OKTI7D;A}Xi}f5^xOG~KeXqMZlp%}49>BI{uBOule_x?G$;y4= zTNqBj0z({eg@xHo5@_BHMIh6ej>8sBB_OLM z9G83?{0V|Q+r=XU0N;km)u2_Bt_D;=)cRI=pe1)WaeIC$558V<8W+Wk=fH|kLe&W= zk*G=Kp;XV#DS?7Far(HtgR73F{-Pll?>!rd^PRn6t1svjV9`;c314!0tFKCc->Pkx zV{x#i_v3}#8@mB&rb?6Am|&4yZd`1a8{PMz0XXcEDEcpZa^^G<;Yj0*@!UB8IP97> zV4EfcVU7t!w6((FJ$rz+UDd~ijdVBo0j3E-iZY?G(TJAT!6Q%&U=AXlEhzV>Iig~S zKCy1O2SUPPHT0JE-jrMgYFC}DfPLDC-^f;lnl*2gn~t5O{F?KfwHmU+0<@^!URaj~ zD`y4~nlfZ+fkPgd8P&-njPaoIr&~HDV z0$DO4NZ7sTS1m;sL5GWortH9Jkham1O0~--^)?LLG<7;aqo(T~MWj5cQ$$q7m4hnV zIk=Mn*#IUwoBTRz_xp&$XuK)qxx{u0jxvZ}hnUrKzMUNXsTxqm+bNaD8PA%^lemRA zZ$vSF(B1-zm`mmyRl0a4+RhRF*5To!F*!5p#qfH8`Wy6GXcmsIrOL8UAYPZ?h1eG@XZ?#wzM|YvPa`mJdYr9wRm2 zd)tKo(l*8LUD}OO63mI4r9GN?Q=K zZh~2WSk%P2Z399CsQ{!yHzulH@VhMZe1B-0lc>()aC&k;fg6Bj6UR~Q+#>eyF%)6^ zOxFIZU&d>P5>`zq<=xJ-O^e*3SOnYsax?k z-MwRw9%{KdrGq}1V*JsNJtm^Y5yASSyEUHwS)Mjlgc`6;_Rvy2eIJ^e3}D=$R;rUc zP%BrN1;~nI_}seybfRV2FbZ7YWAr zLnA(&6|%S`J+`ZLEdEi*l?yZSUJR|N1iyfbW#bW{fuBwyp-;O2`8j=Gsu?31Ap)1` z7Ua~KSiI)IDnd zy?RrXbSpj&;$)DRQd?WQTGayMvNG_nP&3v^CJt@PTeZ|%sm^J{QcZ!{tp#H(o)v_0 zOmK$0=Y_BVexq8f93a#Ciw$Ygmvb|5FOuVL%CC3E(YutuobCNFVNk8T z#hhQAp5kuJ=WV>2K87~ciRuIu=42z`8soBd>TKif!u!teCi0)MSIwd-Lp_2{U}3r` z77UN4jlm;w^+J%jDg@zabT?#S8be)zPGxaJ0~)YO-lwPGCa_LZc%wTtmv#yHp-w?3 zxS%=?E$$@#AXf+6z7tgTa=S{n#WRQwbp|@y#c_<}%Xr~d6^EFXq2uo^n_quMs7KH_ zFlraL4RlQKTqef_)y)XjS`e|h^wB2GdO{t7&WRz@U|0~rkFwmvaP&u-d9 zgfMNPEszU8vr`1p@(`px=A&cn8_!y`=FX-;r(y2=EYSXc?%pflOIcSz8bJ*P z3pI6}zGGtrV?d-f zjzxi=dWLfP%Ue3Ae;RM>b;$<$AQgmK71h}@_8_@$uJfKsoSpnD>ZGy@U6_KE#zl34 zOz`*Ayhz5pDM$$!qy{O?>egTfz<$^vI0tAzJ(tQ6-zv>WzW zN(~y-Wi^GyV+d#(6V-_-lsI7AfcDW^#f9XYh718B2tXYj)yXI|%}CO>V}m(RcHqtI z5vcRUmW*G=S^p44EWra2*WRV$SGBm({xMOV9a4jxJq$3Rg9nO> z(}9L>+?Y~rtI=M_uV!%vOVybl#x6U8$;yzP0g!L4Z-q!_TQ|9VO=06o@lU}Sh2ER- zS5mKo1kbL?W{g3p`gokV;{6iA8Jrwul6sKSHa$cep3P*Imn+NTZh5&Xs1$4p*>%sI=`Zh*iQByPTTvCVvv3<n_#`48P&NI^xi7aMJQ-fsGa1U zA~yx{l3c}A0tcTLWdG+$C<};1bzX%NrPD&^r0VY4+Kko~l<(38X3nTJ7vZri=0CAbB8oJS=}$acJ0XzT`IyMZ!37VpL~gc+L_LtRi@Fn8pT7AQIKe z;Gk4-BtxXKld(7_)YH*wR4-5^RJ2L2$d-Lv%0wbjoq3`8^qDPODFiq~{WD4V)!MBb ziDqkxdU0YRs&g+8t)Y(z_Z@PZFDQH)Fgg{4Q5?mh-HFmqrusO`1IDJ+ALe#J*Xb>R zJc67+PID%@9<`*Y1uHN9_C6=$1JfEXGpf@vNEJaQQEkVdja{1{ivFl|v{p{Xu4^g9 z4;Uvc4gmDEkcq^gj|z4c@B&6N2c^;0?b+Bz#xJbFccHCKqB>&(#dPd2aZ3-L(ovax zt9OB)u-QwfLYtdJbvg%LfWXqy#dd=NwjA`+Q~Q!RC7pv-@1?|2NKYVl)7-kTo2^uv zc8}X}MupDpuq(cH0TclxTuYm(2xq7jwog$L^lF{cVNWFdKbC$151772Q(f2A)X~(1 zGzt?8H9=buM6PPke(M3xg9Imang@M1<(^D%8v@lcArnf+d>%DYE%Fa-Qc|H4KfvX% z+m7;b?b@aS%!quzYl02msRwP+K4VxigX4`gXV9Yd&+7i0HxDgCAAFi0>O)5yd2E_e z39ik|(w`QV&{XIIkQr#_z#XDg(`h@EHQhS)!{Q@>lDd&twEivRmE}nZOC2#?CxQ6A zu)VfHgke%thDZ@?f=0ES-D=VdT_iJ&SLn2lnJDOCqk99O1GMn8b(?+W7*#EEGBm%m z2(vy$oTQUJyp5A~Vb$l*@SF7uaz@P4xgL6DfYeuu;Sm6Ey+s8ofl8VA04J22iW8|l zEpSyA@UNY6Doq3IuP2<$1of8Nw5xIGuoHrnR_I(2vLG&*Q*UT))iuElLYR@Enqh(F zsy5e^Q7vs84!FrVaLR;J#-rg-!=~}z`ys<}kAGQooj&~qpBd0H?@@9Xp}MRQNULgbIQm5#k(fE$83SiVvu zeP%;#*B>r zQdId&X^ZQoC0uc3 zh*PgUonPL9O+WCmbFt-;`VZ4~^SU%xH>l+_VJ&vJ^|;}@6tB{Xc-hgQ9_scrssy(z z^i?!eL)COC{NzeB9%G|P6hTn**?~a7j!wLVBN7QiByl{p_g1bYllBsbirsH+pWa#2 zrr4E`zJhrS4bBoRv^x*I77D zR;4~eS?QwI^Re{_`sy^oXSc(%uIo>ziR%m<91>xFS65Y)>DkVT8zS2&yodisGEaNg z+DBCA+#UZ?icbsQ0eUpx6NF)U0_B>cnlCR-MH8Vgd(inj=yrVC%l>zM#xpnunnX-%vN+h5WUNcH1&a^k>g!b6vev8vue@rq6D_aGY-bzNq?u%bzbKQL7lW| zqOGi{ChS17lLqDG?1K@!!g(Z=GE|{chHR39XEMvu*d|Y@B05|(<8|H5wDjuWYN>s- zb6YkvHKU@(F&xbw%I7k1xFn&!WN0Ly(~H!^@{@oO+Y`4C%_cX{j^?^ngr2|XR{f(r zUSK4YVN{_rjMVviPHR9U4$h*WH=@$4G?ZObp|gwp%MHB=6*tuJNvd&y(l{+d3MCX( z=!7C=FTB*E@&W`U1uUGN;m=AofGspTMJLEL+Dsup<8L9@^zO#*vf}miN&v|lz15Wf+eM;@Ma}QME z7w{5Q@RA+eYifng7~)21$SoAqokr)0YJ4rKjTomw(D&0-!;nn5^#q+EM4y||7q>V( z3+(554)^TxFw(bfoc9GhWwUSZP9=s)IrX9nod#5`7(QThx8USFaxZjRjOs(=^b&q_Rl(<1TgsI}Yoq4ltwv1JNkC>TKx>+rLMKseo9<{14@L)wq)dE*&hc54-cAP) z(!qer2$&B~sR(6{)nNP5;SP3%GC-h{dDm5#q#Z9iRHr1EATdf$&ha78lx5gwg61r! zE8&~?kHFA$4-II@9?sPHJMMRLMvpEkgh}&MsqyL(ltoR^={efdm5SMgUI*{OOb|;4 z6}@Gf0MkRb-}G>V7L99+PRdb>2)3_)0}tHuzELvRQL!2#j8NyK z!YL7oRo9mC8q#W!S7qozsB>@JP>wz_Hym(5I6ZH~lepD#!1pK1s?@1A$_Pv0I%l<} z6(G5p_K7hCMz!w%>pBCfMzcw>sVNmYkH-5n5MbM-!i7}(38IJ7$uMMXbT&-J__ztp zh%iS&=(ve>l(UOcEYv`^qiSkVUT0+8CB7mxb-T}b;1=@45eN) z*yO;C8GXnw_Bc2O1CDV9RE6JjEg#cH1s1#=DGezi=xP4Fqm>b~pCP@g)QK;OdZa=@ zI*>wzo?cpurZk9rGyQs%vW$s3rNyqvBI0+g)eHV7IIzCs+|=ZIBs?@a(qlk`8^4^e zA=Qj7x2LqAcNJP1PN>icF8b=LB^f-Yt7?`no4a^XhSgLlt1m^6YiK}u4d%wjiCM)pkfZx`-zfDY*IjixC`Z$wG^qtK7 z)eP?yD<{i8(XV24_%EJLw56{~#sem1hWB>mljV(n!`uD%pZG8PSLo-9{aP7sH^Y0o zZIk7JSk5u>;kEdFD?ZYGnkbL+FU{$k;l13#$ubqsIaaQJr)02P@o~uzxg>w+NFd-* zV0QuY;%QC8+{rLa#|p7Qt+q60SPn|d6*;4M=nzs-j-E-GLwEIOMrWrX1m_Mz2)Vb@ zT@f*CDa;VD+Eu0*ovnrlG@~RDH##Cl0sqE6smuvn?JCubPAJu9pO%c&J~2@2%8IJY z30Pg@O#6(^jg#f?KlA-6Rt~0Bz;K-zpV0|*dip>9U&Sh`0$$Qprx~44r(6GvU+L-; z2gfFS)Jh7Mu8=m&&0iu51dC9Jk}h=gE9 z-|vSYNJJuzuKE54ud>yKM3fsMD%I%0EAT8J z5~)m7WKP^FTZ>4@HbY325&~Xri6fnqYH^81HAGoTgOO< zVbIaInh`8y$`<25s8L7{m{eQgAR^(JGnVRCu{uW+N(>gRqioj_sX(9ofQhv=ki-}! z9Zf0`wI7wJk<7xZRzZ(5zm2VrBw~v`BRYIHvkeSbkTJMxts2v8^sEQIpQ);=JXK8? zs;UEau0YNAVTe`nNPx3n<>_rAVGL2L!?_YYPq-2d@hh-DHshUFdMceTR9eU1T!9%V zq}=iMk~3x{E3rW^^OLOfbUk6{x{kfMvNgrWgvP5X0@ja}p5iAA#n+KFSE6PGkeG;6 z1S}>iJu65UR-j{Pu0+iw@QD)f%7C?HrDqZe!z6TI%#}!yo~xFyuz;0jrDGr~Ys~dd zN5VXTuBl*z$z&D62KtZg{8l=q0)d99=m3}}P%|9#oTv&|)mA!&1A&I&=#ZBqkTC_v zaH7!5fCX=*V>l3K7>*8SxdIKt!A|>Fz+$-4F&s!V3`YmHT#26H%mT7s5zkyFV;da9 zfk4A>bnwd)=mr$CAut)wTtXpG#c@p#XjqF5bGZTyYrzK8c;@;Fi7MD2iH5c4(3UIF zuoi@GiOjVZ674ku5)Et7aV=M(VJ*?hcp`Hlj%{$P1riNw(Qz$TqHZnGstWiWzj8yM zJB`|Mf~7RSj>t0(b5*H|DiK;lU0I1Q znJFUenS;5G03hH|xCT%WsYFl{@a58;0hr4LZ~+pLqv<@lntMo{G{bj~6XuJS?zTyv%)g$P%97aFdN*c1VpW-*6Czx7UFbM> zL}$NZ^hC#x92?+0Cys+hxh59i?9!gnE;Jmxjw87O4F_LQSs4p(c4<$C7a9&;N0VHM zx`PL591rkyjh;p?G#tDR7a<1@1JsIXV9TSWjA=n*kBl=zN^ZW9h|0Qvz-RdE*lKH)OT9B zvioM24W3;#7|x^iXr%`O|fWvaojOMSPME4y!Y+2Glw3DoJ^uw2=Fv&#l|S@Yp{ z`X((`cHiu>!Cmisz@ENa%az?XyKHb5LPGpBo7cB)IkGcboQCVSYnOxz>aw*CS+4B9 z*=2*fG7@^I%MQQ{GEY+u9e2HJmxM9uvNfKrJMO;OWxZ{e-RT-L9@Mvmxw89am-V(? zl5E2+^^Ib#?7rD$y=|8y+ptT0=a?(IZ+2O4+a<|1)=PcIm@B()c3E%RC1ji7roM^H zmEAYHtheowWE<m zERk8gZG9xpus(g`nEmDmtAAaZ3|<+ty?x5IK$34*AU5ytaD$C5yEwIolQ?5B#FiZv z7i?$Q#i=-n#2I#mrmQS3*tD{XQ=t)wGfXQPQ{sZHDXTcon#|}k8CT+h4Jf-fckax9 zGnr80f^8;}MRQV~&6qJ}QtnxsJG`WCR+93p#EdGjH)cs`&QV!V2f|nau-%wj|4rAJ zfh5kgrV`rll3+8*F3+1g!%R?$QSyS#BAYz7T#WGY4Z{o!Q8`rdf-NJvJl8VJU=YVlD|x}DkyV~&8fE~93ZRk~Y#Z6-IrHZW`cNlR z@`8;cyF6$9e1RS+ek@PA$Oam>q7sK51eB3$ICyN0YZAVIE+QAhB2bJ*<5dM@RO09x z0=_b3xT}RPaKp|L8pp7H)O*#bqd^QtlB^04<4upL{t;Gxs%p9*97%~)RD!(Ydm*>1 zo%TgzsJ-!EAjQQgDskLRv?2-oJwu8&7E{$hkW#OtA#o%oQCX1;5aWFz!}X)KWsA|k zIEW!!Fmr-eyU`RCiM0q5l>=Lh2FC&Y2M|_~Il-%4eV$?B%vjX_TSDL3#p5s(AYqAs z>2(97878!hQjjyfE+mJM08pb7zWmecy7d_*{2RF?HI$XkDO6%pRb^#7Kyg=lifcl? zP!{;|;W^M5PjgXhh{pqF#M4|8^o^j9&Yv0oYML9zhW~iL>$vgF3={Z8okLAZRM*@% zurYM#_fLvbS?^BIFk^k}d~l?=nhTasyb?!V1xT?q7lG7oAjwp_sI9&DSAVSpR;sMk)6aC@j8kF_9ScC3(ZS{IgmNYPMIBI%+MTXGdt6x z>2CrJu*w6b$J1Xk2*n;7phD1QpnPzJ9AyIj6yxDi3l!X($SPuCIp_RQWR39Z2!UV(NLN?dS2Y{z}mp z;=q8xxKWBP4hN&2S3&%%ivf!!bGg81T%GoX-#EZki81^VQ``-K&U{sy+>uD7?ea5QRPqS3B+U@$%v`mJsv=5c z{l;hT^g9`gR#s&w=2oW$POoX|H;Uji{Y0Wanv392s92&3&4@G9(hX#Y5~v57sDiUv zGI8Ej?l=aLu~Kh!>fkgIQ@K$Hx25RHjinj~$@s_Ol)_1hsobcAvpV5lT`LnY9GFc~ z^aKZk@jjO6x^Wn*62r=UD)m$Utvs+U_h?KH+)!q20a@O6G6N!1#g!~w!%qv1UaZnAAy=A5rkm62{Z!t%8 z-2PUcgC-hvGBdM)6nA2L@qA1vFs8>58jBJWJg~pub7-!3ab*)j z<9!OmqigJRi(c7u9C15*$vi7F{G-_Zj0Bp761NQ{-ly;->L6q!&@_~|Z77+I8AC_t zYy%;IrlBOt<&MuwhW8Cu#{j*LY#IvMF0#Bn;p&j*eq$eUkccXIeacs(4vvQR^o0Y8gti%T);Gj#E*Eb_^Hlon@%t#QYT(Z2r*@y$Rkv!8z&~uUH1)Ip(!F7}9 zYR^P``Mz7hMJ)C^?38n=p`e*#g=p&JQ~VI(blG&RECDs1;JR)f0FaQEeqM4^N#88S zLFQ-zOp8e*)dchj;)%K&U?9&lm?W<(5{G2kkvi6KY%?Q3^A^0__F+@9V~GVMLXcfIb5JbXT;c12b#nD__BNyU}-QpNj+GKR)Gec zK{om*=C-s>B$< z5=DP1AEk`M}5_v8ZB6gVslU;V1hk;HtAV7NY#;|#rkM@OJrDIDin2aHu_Aa z8Yk^oAOE;u3?hBNIxNI^BL`d~DTeY!%jLA3p-1VFKK3Z#46}fNxXNp$_{dUdqtbAc zA~f9vi@YM5IVtY8m6g7{9tj3Z(ZhV~q^UqzBx6e4h{u=8BfC&CyhN1-VNPNSbKeeT)`a&m+&8K^N?zaGw}YOMJi~qCs8g1gV<<9c=~c0S*>)A#m(&Ag zS2LxlaYbb!hCR0#v+b&}FQtdlD;b&+S5#HndzJLr?s1SadK*KDafqpsp{Xzo5|ugs zI3UCEH2!UW5mI4NKP_FwmMJ?Y^9{sNVqX@I{X8@fU)2*kXkZB$^NO)J9@v-0gWk_# zFc`1u2`PyL3LCze?eVsd_;>!HYCwY-n%NsKET)4%cZ$r&9b1WQfql|y2y~~*jNAbw z+S6sYWgs3lC}hsM>z1p{>>d?vTa2d7IDZoRBr{j69tSLg7MW3cluDt)`=RWosWaNb zmS-+l5aP{|5t-wdQXUIFoukmFCJ@s6egc|{VV|VZ0^_|L%!~$Psx>O2JRVoA@lsH+ z%q6SGLCi>o>6ztJIA)_F3K?-5BJhpF`%Fgc4air`uTc?=R-z$V=7NQxD6Q_^;M=c< z{g-NL^ol5?Bq1k5t6iWBQjB~QQIR7>^Uv5oVsAAvU&&Tw8jF#HVj}HVGUAF#e4xxl ztH(vkAjWjdsDiS+8`V$>xNNS3Z#3S_nBExGP$foFVDK$s6;+vwUyloxVKhdXiNi;o zsnIn!maNKL{vbtZFinlA!S<%(K2}3}T-Xc(O*OW+AP>zvmy!KYmPj4~y%Cx^UBRxp zkJV7fQ~FJBZ0a|vq3kI8Rt<$f_j{Tk48jFlV4t$f9v5EQP-B8HI2+U!*r)Uo0^KR} zxpGuP)hqYSl{Y$=F-B-w0;-`(V4orsjL@4y(VBZX-!7~&Siix7wss#4UP@IhxG(yu*P;6BK z`(`N4?g|oU8VZW7N?_j%#obZ?fu^BUv7sET9s7rv?GMx-%fXwnxd(SE1!S7Wg4!z& zGV|2GP-AiTPi*jUrlKgsDuI177I)Lc1|NG0TgYvJeKQt!rvwC=u^Gy;YJ`0=7I%9D z1e(@|Lah?mH)C=4L_nZveW=zdfqgR;cUJ@in%0N9trFNbV{!LIK%g1Kp@gdh_RUz_ zjSvuMS|6&pN?_lNCFQOvKI9X@DrL$;W5FBsvl&Xt4ZnQICzvT}fU!Pd`#mW){POXh z(67oC*f&E-In~V#GfYGjaHB1-Z-$a`!!I8=8b$4wze%ibhT`stzz9u4K^0gD?3mB79kin}oa0!>3fg_r~aanh0#bosIO+#8vaQz7n#6w^9TA-1JB>GeoX zXR88|Vy7%jQcRPGDU-lh+|;@PNik^UTsb$!;?#mkin$8K*$#35=6VE&I4BYUNwHG^ zCL!j^g90$UP(M0Y&%^BF;KBxE#ZLW>#F&c>%Dy}=aUC&27Hao-^1YE0j``73)Ou|x zT5gSAM2Uc;c#Uf#UiC^wZXHJtG)0pz2jkj^A3{Z0SBWveA+)zi1|-E!b+~(j zA2~%aSBWul>v$X#zf9P{sR@%9Q+-jwwWmf`UretOV!o3bTKNG})NM%$ou%hgdE!u) zSSC=p#?8^nR9E`Vi8zO#6l!GV8*pT^FuIl-AU*WJt zM~bGviAW{7lw?3mPVJS(Vt#AXUe#+E3XJ-U&42O@#)TDpz6vE*CB{%-yb%tv4j7GN zlr=tQg-WXuV<>O}C5Zqu*eS5mOPSs(VFxN%>Z#e5ZKs|}0!`1Auw8M&MLOY%Q6sF% ztXcLrWmJ-4Ixdt^?eDH>GZ>0hikM|gwNpHW`!ngBK$s{b(Tk^vs#q)l{dJ0`B*N5X z6is=W&Ejbyh9Y66E<43j5@YHyil_WOM)5Qe1F0}mkDcNvNikPn6i;m_x*o%y2P|_= z@sy;PdW_hjVO0U^oV%L=V$3xc#Zx85)MLC-4w@E7}tsVcwA`3$Wn$T`xa$8byS*bQ;$(crMDZJ434sA z2NNQCoRTU8ni!&SYN11hsNloj)Sf(?7m7_|0ZZXZFVHqoMD&yO&U5laYQB38&hrEf zG4pdc1y>rTq3`G+6(rM(LRLd0D2bWM?`~UwNJIIJ^9sFT28Z6Ovdya-R?IMqMaCh8 zp7h{2JiBzq=lhsm#-W6s^x&X;PS&wIOM#E}RiU3v=t-(z0;6emUYv#dfj4o{o)~&HlwHPz(a}JS!mL+Jc<|kjFcRU@6Goc0NC?J&klRWbV z@oTxKIA?@>FD~+B>Gh)6ir*+cEFxC@pXH&OMWtMKr}(-ozf+8}F26(U&iUppF*8@b ze~ZYsj=x6?8Ax}&CR3IeEo&bYkIM3U#i`cl$He=CdSCfgnY{D|{gc+!<3vx6%qthu z=5I;^JbtXI?>64w)$W%Zby(0J`U(j9e|&$=e7M_QIkO5T$V>1$>+&VyqT=2?@9+cuSC*|5BdwPPoM0fsG9@-@qST{Z< zuJ%usg~?ixLpS|R9;^~)$XADnA#&xb`O9wIjQ??Ql_;|MN5!Xuy}7e6cPH~t-j=D^ z1tYBO)#4g8WfrEamM^_yt*I6F7Rl0xXpkG%ix24$f4A18@JDm1E`5KZe1EklmKU^% z*XXW)$g(}TC&<J-buPDst89biVYyJhVp)m*3efQl_@q6G-Y+!FL|A*6b7CD)ea@O^LpGiPDuKH^~>w%R(xjf2ez8^vNimN~^aQ>{lY6SWwj zp>;G@Nxtb{a^D?dqV>>CV)0STsKzZp} zxTa4#MgKwOEKVZX{r;ca`*3b4>1)1xZMzs?J$1R5kGIH}&&7Ouj@-LPG+2M@6~_$H z<`c?h(f8`tPnJ9=R$0Zji&#$3gr3V%a%JifvB-M$2~jg3U_y80k*H&PQ~zA690nV0 zVU_r3pgFxMzOlc|xlf#C{m<=UM1ONkn!CNbKgrCOsk>l=zj#oL!>zWzmE?*03G3U> ziq-uBhVx1xT`!P3YDB3#YNBYf8YhW6a?PRK#y1U+sXOx@eny45Q5WlDqk)BDwDtG0Qss4)JDg)>(TtpI*IKR^Kk-R^h|qBiw4w+9NDw zh}=6{Ot6Zc7XxwvrtZx_^!pOIzeX&vCQKGT>SxZ{qkMg+Jor+6m38t$aj>5|VF&rr zFzfBJ#nHL$WL?gG9WD>X#R#iltN2&H?DN#h_Z}rna`MiR5ME?0zeqgP&z!M6eAChL z&~rsmxix{=A9I~}6~oM!wkHO`wE7)07QG{;iBWRe9b$&HVz+p(U)I@sMbO)ikvks7 z*O>E&cpA6bv-f>|>~Xzi&o5Hi^8O4lq|kl&URLbm<<2Fd-umw{(XY^*fhxXqg4}n$ zD7Bt%6f+95&p;X9d!o!qi6s(R2S3my`WKoru#|5)$-3hT(O4Mp-f6x*LRLrej+1S7 zA!K;=W-+VKeCwZ*qwIIG+YZkAMP-SMQjpddh7zQHzHCfmO>aIS1g zV7LQg;_v`dWw!B6r^tho3y)DQ^XD@~1a1xi4lO?q@by#Wj;HfSS-)K_P9Nw_-TeL~ z802Z=s~TfzfU=FT4FDWU4&^q;J2${9#5RZ*2V|ejI13)hx+bB4Ap7z(#zg+*zD6mi*}utAAX4T3}A=b$ruVvifW> z#mb*8J}Gc#^gHTCq-bKQ51|Rd^%6oVIW34=UI}~H{I&o````FtC z=R&Ua`Bsq=;t#H5Ay^p?UMwjvJUf`S1 z8|{8E${O`G@%x;>Z%1MNn+5dB*hGAXIMzD$8{)6HH8akai1Tlt8)Nduabldjac=Qk zdEI!?Ndei=V!9HSsYwMhIf#(!r;0u1r2T>Nj(!Pw^kVV0`{4%j50kPaC8oa z+#r4)Fnh1@J(Fd%CFX?ZNS{$g({GB*`MSVkkC-Ekp}VKb{rv_lRq0Xhcc0+Donw_x z6R#BW#8476nr^I?2QL-N)xvPrM)9kH>~Fr1)q1+D?w@nKGW`$E6Ga2eSHGBVs==o7 z+?m$ktHp<~unf)Fncp9eo)ME}YYIlw8d76bNb%Extori}4y$I$ocqN&*2w$BA8@O! zKYRIsvsBVF!V>@PA7FC7=QU_H4s615@!z;W9OLGUl=s}l*XPKclM6Sh2zA~Z@lE0C z(69LVT-m--%(PBjCH^E_{n^Hs=E*}Z79_1>Hi^H9>@(QF_s*B=x53eVuuT*dn3H!i zUtb_=#}y5ud^X?u_-ZjAXa?`&I~Vr0KX%H!yF~Vh`vI>=i{t@>s@6yMi9&DUEEcg? z#eyGLVr0<7z0Zcb#QJAK3=-y?J;Rr3Wpx*_f|KWpgZb`sy~CH5%J$XbIBW1~@gblA zB#e~&T*sH{p8WkfIKkJ? z7kSo(^TqA`&8hq@-?>gkCW<;27GeK!uH5@f(P*{c;Y;3TU?U^RnXH$!FBRiRsWxQq z7q^Maif=tChku%~$}c6?W4HpI$a<^%M!GU>7s7amXs~wNA?^$YJ_g6fR*c)+w(*oP zxUo^z-i`b}8~8DuJw{qqkLo{;qNri=x5LDsBO@S%{JRaZWNSgxhk#7xOB?0Bnc^g? zp;qknU=RX0`fZZ$t`f&v>r-M+2o~}Z-P$B;U(XvKh=oXCA)gJ#J)0wG6tS=!ra>Nv z7mSiOCX1%Z#TOuO$p(xR^8mN_F(wlt8O}E~^QtYswOce~g-93->bF(ycwC%l)$bEe z1>q#C*uk{OgO%cpAe^L(ueZt_^F)jF;&c)7Ad))1)F#W`&)sDGV5ykoK_m=&^lP`y zt`~QQpd$zQT{>jy5RS;&)(+ord55^jhm#ED$8^e)^WcHLbD5|P!bwKf~MF_&_Ri&C99T6R3UF(imP?h#GaUwg%|K8)n9oC4f@aWXa*yKX3n z+;cmE|JUylrMS`dvJ4sZyM%C-`m6}a6`V<3YF$$)wj*bAKww(X7xJYYvaGtWK{-=1 zwY(&cJnm)6;~rS5JZ`@A`7)8?C7CL5yj5tTyW^)JaCb%kdIC7HMI^)Jh^xdSI!zgsRwdr78B6Tc$& z|2y|+>&diOFfjYtbSjIvP9A)*U~blwav9%rz4f&#MLqDZjF568U%x>CZ{dmL6=cVE zE9~4%Bvn?ulbmxzrQY+tB)*BoI^%J_96&mJ6EE1U9}R4jdu|g2*7>)KtFnV{@AHT4 zm3to$DQnAv;ua5l`(IvkZ&tA4)@K2y1cVYNGS+m9-2VY88w{>pF;QHYXDa?193|X} z(nevD6hGfOcRo;FH;Oohg-E$`G$NO_PQXDotQGAZ4)+ZIewQqXh`$=PCu2hjbT zXL+yOnV&OD&EgHsqCEu7e2#zcb-BMR?SOik%HG<84f4IM zh_N31il`03Ha}-+mQwM{?m%RkbtX^bEZ`oQb2nhnY}mPPF5=Y2H zlPvVX-u-_cmo*XH%=bJb_pTDFvnHY!@l6lQ$lX|oU%XYs24tP6+jA%=d&F7ZDrEad z1M8LRH51b7IJx~sOuqhL?pkYzB}9IJG5?6?{ZUz4DbA8ZHj9DQ=W&tao7WrorpK%o zXN#DJMD6Fl?vtrfl$J_YiPybkR3(^?%jzbv*g9^Lcq=3sUCd&hko$W8R!+WD43=%k zWrNbvOZmU`{+ukSDOjXZ@jVO0dJl`M;p@-KvK``Bn!Q0*+d1OKey(!A!DINA zY=5D6v>QMbSeI@Umxh3I2l!Xtwia9@p7cTV{rG|3k$dAb;Olt68GiIAzUjNxg5C7{ zAS9L0xG2xxe!1@^M8uCiB5FNE-mbc@-<30*JmmM}zP5p*tZT-J?KuR(tz*#Y`@K7! zI$pWG%cqEoe8}Z!zUK$MI}eq)h3+BNZHvUl9CsC3&G-D!s$VC*<^h4Pzk<;VO)9=s0buZ(+IYI;yeFMj+v3;m;Y z_!&_aG_wU95WH^!Xo!5`2C*<8s;uT4-%w%Dad!yO&%`>`@vFZnQ(s4A;MqsTEH{V@ zBp+Q*HvN{2{C!AS@8D0TxJCKFa@24P;@-^&%bOG8s4svtNu;PN2SMClJIA-Rc6OyZ zOOGB)mTq+Vi$gY@}Ol#@Jf5?&>5zs$# zqnPdSm)28=^sW;kX(eKb67h@X9UovbbYl#!2f zYb@Y!`+SMc_xSopGUswoZL%dgzv7z?%YAXA%(K5r*-*As`UB2rKbB=T0|YX29F^q# zt9S3dk@DQPiu-5Hb4GAH@o#xxN#P`w4F-@l-r`yLMAed+4QG-zj$vU49l@ISKTOX743PU4%sWaqbh{lC^JUlD%}N^job>z^wC zI6S>6pr|zW|H*xOkeQfK;-@4fH%IQ6E!M~jpBG;Z(7MXO$OCgxk6cn&#Grh>_0VLo z+!rhUhb9PndTK}Jtd_4Nk-wO+;&_Txz;)Sic;FQ4&1!MH$Ev%N)w;htG^z;nBUi2e zP%B0%beU=<)qGRF-1}kfDC=h_5zPWG6JcyD-z#LKStu)y9(w0+eMl6!alJm2s(b2 z(tzASa{t=GnEUR7t^5k{i4PCGobMcLeS5l??%~Hz@n4IqZ!e|4I@Y|B|5_|_Hlx&h z1a@5w-#bKBw~3_nafcY-o2M?mUSfUwGI~NLY;iSTAF67P!+XWwb)@swUE)1@!C{K# zh0v)WkX!%`I) z<;y4T$vy4XIbyz?JppCw_a}*Y*10pqUXL*H694WPnOaqN2Gu8vefbP$Cb`GTz0VJr z;PT{-n9qERE#o*jWFZ3P0N&BNeEoRYE^_J>DI;5ElfyQ2g50|sl&5gQ(FlrIb5FDq zkBFc6GaI^clB|7uh)pV{q-Gw48@VH7`{bhW%D)9KwI zE0dhT`ATk?Jg^mr(-Cr;U-G-2VlBE@JnqYA^7sj-%0oXZTBK}-hmkF}IfidPO_tm& zrdr{-O(lhpxg+Ji+eIWixA_y@I7+s^Q*eeGFs`RiD|fV4Ko1BQ&)|Dbmpcy@o+htZ zEVjE*D9g&`_DK+>ny{-zZef&CDp0B7hoF!D=5p#CGdv>Kt`-QItLHi4?ibZg3!;&(yN z{+om~=c1cgBPyTSh@+44O;I^*0x+lmpKy?`SID-B;6R(Dk<0lKxIctO%t?!`-)v;9nEG$UKe zGnVg}rb45DlxH5rpCEqG7K1O4@|;h1Pq!{EM=jsW{wRB?p({0V$K;}uIaSZP)uNkj zoMBzOghbFHO<4=2BDphVCSo9#gB>G%v7Z= zN3Nexc)AzN962+T*oAQc$(wJ1yLl<1484pwlVgJgF6qs`%U~N{Unma^A3V#q%iuV^ zv`8Lm#AcEs#6kV}-g@iO4jO^8p@p|)#Q4$@*}e&J!-9HDZ)Ah`c?d!DN>=sS-qgQG z-P#Cxd)Im5D?X0cH~E&O^3Xy=hh$D)t0J^TZ5&ljaW$q1{OM z>h2}GbBaN~V*%Y++d**rYkd7|Qs z&+TrgkV7Ivr^r1YV&z9^qr|#zlUN;6-`K}bYmf&=6_s0$T_%P;N1r`y?b{`84h-H`vw3V#g~)7MV{YQLX`?)F3?dQUD3>jIU(0uHvTm&r zo4x%p*YRJQkf0X~3)&wup096~2O5jVe4+g@YO&lR+ds@*ku}m;z*3v#>#N1l;p`9I z&XT*8lI*&mO))=a1#6K9zAENq-xSlz&ui7HI@xx{+|O%yn=F}9u)y`TMOMJpn0CIi zy?5WYrvz;oRfX@}f<2XgD}w~K4C2*sWvCe-D@9rZIeVg*;G$?|tP&1QBNFFo3ULsp=#FM39Mm{VJLID0h;D-Eo(C zfasri5LctMhp0Ug{o@6`_YS$>Tu`3YT_C>hLq$K~>(^Qj-%Pr1Xyl*RcYaC!>2|Rx zDBZb|&F0H;|H`6sRna3`-2QEz(67jYSBQjKeFL`4T-_fOirniqHnpUh<$G6Sa}Ggu zL4o`;Ebe-_^SFM;TEAZ|MtQuZwS4IYxo=oOO77W!wK*2PUuHJ{;6~E2ky*)2+xaH& zj#d}chVPf*tuDDY$wT*ok`_*Lx}TP=UaF*@?%OZ(Res#fa>v)jDOoumuW|r!i`;i^ z;RtfF#XYv`glEEM|V8od@Ue4{np+ zAYNU-ri1JG`t7p)xuUA9To2wTko#3x{kT|TMWy&zcGmp2dBJ)V#Rjp^x7}bLKWeu% znaa0SxmKj=`J^k%lEOEKIG@$EqDGCz||K4_Fv;4 z++(e|kcMI85kvS{_sV@S#0ZakMbrfW`=|0v_mR$?XY!gBUam1@IkUC`ycTrzoC+S>>DYzetD4?>mz-PVp-plJL`dJun}g%N0WT# zV~WR>Z5zznJZbx^cjIEHFTr_&FFlTmZ{bQ+XEX!!H~9J!vid){5$oht;-D9xU(J`E zWa#)vJ77Bb-lwd0x6ud;4Y`{yebajPY93rhfW!M$axIy&a^UbI5R6{smE~#c-TO$C z6WjclAMlLzt|iX!r!V&b2OdCq#MF`LExSJDRWo=?FVsuH}2bE!)o;Tt}7IVL>}yp5>dqBO@&c zHx^wh9uL~_!h2P6zbkj#jQU16cjIl23HQs?*TC^Ixf_4tNBzpal!d!-G_UjDS1uFV z3Tm>`k5;g}A1F{dkbZ=w9|>B$ekccx$BO=b&7dW+XuSA<(E7_5B>Rypd0uR>4owlo zKKjvozW!tDszq>>?rL-q|Me$4r`GS*iP0YG=w!b1LT|}CtL2R&u_X(&@xj(VTg0Fc z`cWbO=ta4A9h!e|Z-D^%(Imd}N97ky|I<8;^_`)3=KO!k_o<|Mob}hyrl>6yNfS z+*>I&TLYJfoB019ko#BRTV$f~RebpuvUXNs9s8&OJyio-#m@?;s`{7cme#JWVx zHGRNRzWk~zyAe6(<2Q&!0f|nU@A<^SA~D`KHM+{sV*J?{vV(6!>Md#zsKJO4nt*iR1aZvYwlHi^MP>% zkSz-N`rl+p3*6Vf1!A#BDxb`k-jR-e?ig8g%ok_l z9vlRMdhSOJ6=>UEGCHq89=!=ZJRnRP$`2)04-GmCH+Ll8^s(H5z7SUU3OSuu$bZSQ zhp{y~`heINyk{OP-P359{I}fSHV_-h9F}eitvh*TR>u@^y>E4l^OE$b*T&)t6oDS6 zXM85hrW8za(YF61=Zz~J|6$6FHKba+?{(yQgdXx=nX>>8m&tHjOjkZvKJrMlB5F28 zy}k1OpR8V3G$DxQ)=ZaktZ!Z_<^_@4E&=MD*Dr?l_}F^ckd~>%MH|#xV*xL=k~_tZ z6&Z&5bzMQSh?55T;j-Q0<*XH>8|cP7d1xPYy8rtzF~TexDM05Zv|Q))r}|Vfs5jS6 zzMd~5Kg&Pf$0GVZUlP{KwW89a4W;?71=hjuV0KYf#?WOsC_U#5jLZGM zLuVfZ0VUS-%fz>XAoW{VUZJc$GskXRgqg!8*q+}rP z80%jZqQFPR`W9b07DNwmd|&uQ@A2=B>)r7*b_LMdW>PkG^5x^@j(Sup7d48wN-G*&Ehd1E_nt|(Fl&9Bx0?f z27!|YSjfr5+L~icds6%+h)*z(VzInZtEftR;A0g0lEBS89B{g%aDj?NO+HqC{^=>i zvK?jZS|m1kxlB_L64ks@WA(CjTkg5Cd>Se_OKOY;fD(^k;KL2z`SZ>3OX7a|#gPTB=&!nwS;fIa)vcYT|j#|F4 zTm@U`OqTDKr6dJ5fH0+yswN*(eh z$sCchOi>E1iHYsL7G8hrkKG-4lhYmU7J%1#vDw|^6rI45KnbEw04AsCTkIjGTBmIg ze+=Pca3`?5Y4YHgu_-5jjPd*aWFyrLvGNTSDfG)Yde9ma&W^Y4yh@~kcp3lT$4*z; znYvZn8O+O|eP#pMWNQ?I-6UrGho#I=i&ZvaMvPL4yqUc_KS^XIW_->QG)o?sS~M<* zm=R$aYpe+?#gDuWUBBdC&5 z7at-ct)hG8$phWMELU=$)fpp$NS$msUo^{K_lRW)k z0FA~u+@9Y!w5^jIqozK@Om zN8qM&1C_j`z5D(#A#0%7!q2O-p57tm1T}wUW_jK+>*<|z-Ki&D#lKoEbK(P!%g#zy z5%daK_Bb%rm-dMTL9Fx_dG%jOVR#~li{8uESINDzL}Ruf@`wE>T3%f)Q&UB&HKk5` z&kG<`Jh;{RS-pscv^L@9D0yq;zD?MNfAU6X=p!3NT?lLFJFL=Y^Zp$R1nxaPc>R68 zevUkpgv#7-wP+7w4dt@6tW$jmc1zKay+&5b^Kh;#yGtyyuD?%octHCwma<;4uCkGZ z7Eq3h9t1l+$~`HFEOZoKuh&|MK08Ou@>+7u=IaeIXF%R0A7kim{QO3l(*P2|*U<@P|LBB+CsYxU+vA} zQC~WA6o0bwdAE4hbV#Lz7pUTTHd6Xw4x28tKB*M>zN!5VU%E&hm|e6!C>=VKM}xhX z2K(6E`J?6f$;jNzC{hK5mnabK2m$0J{J380lP(&GyNX*_#UGDL?CRSx{ zKevE~cZF)pjUM(Jz4micS<00P1=#hBxFl%1?{>}*u9CG=&=B<-6U0(qzqx9@ezn~5 z5LyT^@&CPfqQq-8*U8tfu`XOAuJ9OENAX{;m5((dJUjxqiksEteTkY&rmcf0Z}_^* zMOoIDiG4I#F?L?~l86U&+L_6BennwG;oYt4IjFo&ZO1aZTQ6rR*UKGi@)pTO(+h=l z;8`&%h*xzzf#P{LaMR(eeXdvXO*gt-xbm%^%@U_;DeDdy_;sGhpS?p16l{@c7>6+NqULK@C45_lGY~-v#9C+-qhQ!4Cz7*(J z{K0NRW9*_b2J?g1Sb~3lyR4oF@YGC!RBnT|L7T+zFGNn~j#YVgXo*=sM)V^d)ou$d zYiPh3LGHahDtM zhg6`pv*ZV?n;sG^Ug2&F+uMUJlyCq4_Pzx?j_OJ?lDfP4EwyA@4_k7{#z+PmcRjiu zwjsz6EF)XC`~b|;)z#HfBdN>oR%0ZvJW9gMWFQ2uCfrFf4tT$Ofy4&mJf>$z02|w6 z8A7lp$%gPYY%zob#XmoO^Dcb!#7a z?olA?*De9FK2_cJuh4*;Yd48p?rm@e^UP8%HX*;Nmo?gxe{dytO(B+dAN$*f;OZ=) zR8V>Tt?RjPp*~a#`}yIKgg=^GcZMqNtl*SuFNu5-r}KV#JJ&QJz3N8x!bkEC-bH(H z@}Awoe&0ui?n41voNlQ)b!OGwY^!{OoY)Bt_2oU>+(Ks65PQov$H0Y${NlUZqDcsl zM`^6f^{pZneUcK_pJI)^O}1PG52CW2`&EJB{5JdP@5s?6u%`(6%qfKOu4X^w$+0`Q zWnWEmr^&ElC3;+cPa<6)NGFNf^|3eo18F(r!NCvkf_VfgUYo2$%wMpUj}qZ)U@1>u z>G~@SHh;$fLZ_{Cy^2oJcgc?XP{b&-i2F4qHIFbJ^)X_!;MB$>$t_=Czdud~uhNVX z7FIbvmgVvc`x!|=LlmcsqlA0ePbk3hEJ_QXO@<3A(c?OhKc7G?jEUXE`+I^696ssH z%y=)*VP+0GzT{`}+}#s%uIPX@HeH9vfhJcpj|_;vo^WKOg#CUvzqFM*RPg;I_O~b$ zRN`GT!S{3gx$hC<9qt+$pQ$?2F%ecx%k@8Kd~t3b=f`$U@B-gr;_$R{aQ9SRAWNHf z{Ubd*E1tm%oWsoNGfn_zeDb~H@_yg3v?u4?JN{rh1Ar(E^xcO1W}UldLS|Yu`x*6t zX#D*C72KvmRpu4!r{~Dfcf#`sstQ%*|7s(5OTpuF9JnLwnw30CGiOfY?6CqxuA}+2 z{oKP7z_8ax3B`X>1WidskxUmVF$qdCPs<G|1oK~76m3*kp+lO1ra~T{a_MRxs$d2 zpJdmSu2~a$GjaDn%6k5jku$!h%f&KF>d@Ke)2Uu-ktoZHO#2oqb5p9<=(H9^sUZBE zk^Vm=!u3cw#`(&eu_1I2}K#W zX{U=&uQUYddf6>J(v!3{&a<@PKa-)AI8%a6HZft~pXkrOAUl@1Sm{8HJie2QpE7HJ z9<+D;Z({7^uFr4U$K@xZD`zkT{4bhDw?>EDzp(iBQE>eG2uYz z5%$72Ny*HT>eD9@yun%?ch0bn8oP-(1nd^8Habx!s7jqnweL?R<$-=pU*~p{ef!|P z%HQDLm@M+WfNAGnJ4K$yd)^Me_J5oV>r;8&2__eB6Jd?_Qs&W2=6)|^jsD#^&&LYx zjL$>7iT(Z?dh)Je!YL=muf}~|xc7$O-kb259PxjnrR81!si;X@JKquZTF(AO^>==P zOWwe~`dfNUPRHq8a)GscC*So&?r%>{5 z^~ndA8}PgQ;1ceW6OK7u#(sLA-mTP;f3A%a3Ql;A{^b5xe(*Z_)M#v+dC%^W{9rf! z_SCU)Rw~L}N;&v`Y>*kTcPC&#-9pd z+=JUg_DS5;`M;33{s|cxZ&P7*b0iXTHBFM>(nNQ-+nbNBK;-e5B<2p6O?m z*20SKxc#K%I^c}KEceL?Jmk;W3j_J+r|4%+c1Zq{{T_5;1cSr$`O#nwv$6)0))2j( z>l68}egRhkOvdf{*kHoWNxJTDa(l*Kq;`%c6&JF%mXm!lP72)>7d3<_{c4B^gMkH9m5PKgBV5Jw-*SX02^L4J;}Qw zf7`dYJMg8KN^m#94dM0q!TsE~*hfB2gsVLo+4KPF)9ydaecV6nI#iR7KE@qE;jH53 z&$30X9X|H$+OhLZCIo!6%>#HPlb*W#;4|Ei>s0T##uHePwsRK0I+N;3ku5J(OeYn$ zhMH?sT#+1Gw7JXfvll6nBxqth4pP@3Er(GC=m`!E)V5&xOj7Y)X;T^6lE`*Xo%>oN z-D!~>H+m%UXM=8kEy~h}(%4&M3&gM_$2B!c8ej7A1<_Bt(YX`(8FZze~-&()J3Y(vembzP}G z@!0VzTVK#p(AW$dg$8gGp(snw#$RE(-)uan|JOu?1+64@0F zH;^@NxLh+Vex1>s%NU);R)b%}ugj$u;y=>ZQ&AUMi?ODG;pUfO{(%f*28N-e;s!>@DOet~^X)@0VAy5t7Gy!{GpCTa|T7&?Jm{DuQXLwkn?VhXtk28>+-l>DltuoCsnfJ22TUIud>ql+B~P7B8%~4QZrT2 zOla&Dk!{-++%_j|^jdQk&uJqD@hu^5e#z&aR=i;>C8`;c5vA{(9l#VB-6;${feS6( z4J>x4Y7`}BuxF;X+qclUU6t$1Wpcd+-)5z=77?BUruJRr#cW7|Zbd~^Poi@4d<+EQ z0J(Z4Tr<4+$tL2z$QvS`zsOs4sxAIDle}5O2Od(%*Pr4Rl&wu=2>*gt9On1?tFG=2B2}yOxIPTs?LU7pa6jORCkV zUfARG4W^!mNij0CC|FM_l0lc-=GWVC5;+K=hA)78;=hnJMiguN&|ig!_m#8hFg4()!{TN z--A;=|5A!Hjr-q0{zv<}rS-uLopfc3pQoZ<9h3CvI9W9WMKw|Ph(n!^O?SH7rM)S# zzq!1QZG2^1b3se0x@5_Mn6yrsla2Po{?hN&sDc)gi)O$wBr_q4hz`&_gpRVk<~J8hGWIo@h#z3Br?+VnP~&r0)c{dTtvnVk5I`4B{G z)fC1y@u$LOgXYBj-bGWLG^4r>^MJCYuXr0cDm0iZ()eIS4cY%3WF{sKzkRT2GCTGu z1{mt|C5N~lm)5iy0~QuHJu-H-(bpAk^gxX$iN(7rX~xvJreUFuKICp7kJb6R_=3<} zVfCI)Yy#C$ef&How0J_*<7C%u*z8xmT!9Kr&wHC|ikpd+D2uXSNJ&v9C%jzM^i)M~|w6+}`?ieemkgjuc6RruZHhkx#>A{X{lRMfTh+qq0C?Fc>H0OKct>MYDZ ztaI`F>!Pk(67*xsdx1G6t>lrrP;ZcFEA+ACzVbTG#**0SPO7jjo)#6x9)@le)I?l| zwkn6}hiY|mHdNkLqnniIp(U57LKMwGLL^N((FsvcoFtL0_5k*4q05tMC^`${J8dKk z%g~00Ualv{?+v+1AzE9$=+iwCYs&gP(@Mwf^Z>KLlh5$xt&z}lah&SYlcs1SqmKTi z8q3uRks6NthzY~_Wdf$2>b{y)u|B`mgoK#97E4kS zUr*w_FcwrdmtrsP`g+Bza0@6dBL#hs%Vl%j~Tyx6b=-QS4;bZiW^cX@UK#1>BxZ02(IKW-+4z^@cSvrjMz%yh= zUt|W|`xnd@2e^__OfpnM9>FD>e-`$Xw%Z7J`1C3XMh%UD77Wz_loBaqsZ zTAP*Xv@tua_(-QSs;&_$|M%B~zY?*nCSS10{@V z&-<5#nB}h3L`f@5D6nPJN?MvGN#sDSzk$5>KxFpt{+G`uZ(iW7Z*1u|vKB*e)TTpg zcT>#KW<#X|lBEW6xOvvcKx?2HDyFbeu~4S2>M#Y&ly0sM&UP@>lJ_d+MlS2JVHGlV z4vU?I8H_v2#0(&8ilP?_8tjQGO617*xdz{Q3@ir>*Ncntg0+s4rVo(D_XBkm8+x|n zQg(*!A#^pFBq+Wp5@weFtviej3G=Ndgrp20J+#+9NZPvm{=hoewr>71yWj3(-GHtL zRO19zVKB0#3rW*5Ex^%jfqHV`f{0mpSr_`!WA*h}c-HRevNNRd1uw%D0dleCbN0Vv z#AP{#nvg)2_b&9!CiiH*%OaQC>4a@|8Qqx9WvQNQUtz=70KTdP>xcCblTuWT0)5j@ zQ@M06r@D^e;Hs6W9_UfpiRCHy5E+8a$X7)!hx`XAk+U1#7HqwhP@h`cf(SheiByJDur= z7NEFo5*vQ+Mc&{Hn3S=-fw_?csBk6W0C#9Z0QYk4bfQtfCiNX36@^dnbMj?Y`$_9o$&Kr zv>^i+!OOZJO&EDA>T?p|P1lk-N!2vD@D?ajDVmI_QAHrf76cnSfI96kH+u&{F~@16 z?b*vh>n-$az_5DlG{1rz{T`-7RmSEG;507BbOZD_Go@ck`!oI(kQg@g%bmSQ)p(5z z)HU`PraK;$Vz6Zb-97c>&PZSuQ|A}4b}^)L3joi$9@Cv$6N~*F`u?z7(W-Xg2tGH=n^ZZ;RLiOwhgUM%u9X71@H?AkQv{go4!P zNhCCb8TCjImidW0%iP4bFml5%cWC-#Na`9-a0Rea!r<5T=U^{(EP#&-uUaTFj;b6L z4N;V$aXMik^S4fP1LKQCUN@mOsco{W_v4trG)@X=4N9{&cZUjU%G^7&wH7Z zsjCS~m7Y_u<$dmpyRNCk~CBa`K`A{8pzw-{?vJGaHD%uREzU# zp^UJ&{f?RHN7^W~dIn-Kvd+}L6|XaPh$frKC`B-VwN?ruw;sM?Cuw=vT}LfzBN2RD zgPR#fw%*k+&Hythz6pQG^yiw`T8(z+)U)o%b=86!Diiv~-gQ=7K z7X)Xx_!Y2#lxJb8V*8iNN48)boiGy;Wotg^X|p>G9;Z|;3^D@@T#NlQCRO;hEa+r)0D|UF~3u~1XK(>A8fL!Q}5tFo83nx9ui@YeS0fJ$K4S%xky_=zzoe2 zEJ<`_0(R390xBbu#=r4Z`TA|lApJ^#q^bcj)5hU* z+#PDhtt5SY1=Jac4rnOo_7q^2x4plp#5e<6qN?yhlke1S_V>A{lzl)qq;gJ~z2! zu9qL)^wI@03hm(VNeT!7P-Y702ys<`e#|_kJ%e2UPtkjE9e{jHkctd?R0mp;q6v|K z#%G%Kg-UxoErL$ibQ6Ywcdx-4wqPa6N}K>i0{RlDggQ zKtKXq1F5D*70vOn;rUr&rAE*zm0QO`oYyxlC{8GgXEZ>FG3OZ4h6M8~6LH06t z65^JU)jrN$PL*O(fn`?2xN3@You^%CIo4n`pqvG}x`vT`O*B$6Kz?-+zm14|SUAR4!>Fl)lHAW_pvrTfO+dq$?c@JZ@?cp^C zW`*GwS$w;d?&R0lTes4^u$X>JDOPlr2^v(v$Q?Fp(ChMH(2W1G$${6(pvozC1e7Q| z?5}gDdVp+*v9KI|DFPG}n##pnB(A`@vJ6FHpwdOnH+k`Qfn{ZANRIWpaqfF^;B=Tp zUd|)CdcDo0{X}3r*@Vh+`GbdXF5K4!C`Gpyswp=I9bu~xgjliNL#+c@72~qwAg;bU z$Vm5jF4~ORyZV|=t2+ly3*MeV2}EoZYW%5Pqz=nyWJ4+FKgg~U72_5TDpO!vz8(Ys z*b(OJposKK+C_fO&^QX&29y2fpp6hFGGdyXq)Y?v0q%pXp+dRXEz!1Y zjNvP>!qD(g4I8=FVsp6Lnlbu z4cRW6?0UeDYXr7N!qbZ7G${y*83(;j$+P=k^}2#obf}bqg>d9F*m4WpK(HHYEkI~S zAdJxxg`EbxA?UiAjFU?bmo<1nz(QF-a*keGd1)EtBM_52C187EJ!kRkvLJo&s?F_XH{=U1?H ziePGrDkKt7x+h;on7uNt+YDK7mK9~SjixC43s1vRCZ;Nd5b>vb#u-&USGa8lB z$$l(1gl62-Bx91PB67Cs~Bg}||H zB?a8Pj5s9KaV`qIsCv1?!{iq+6gV@XwRYUf^zkjGnd{4tNA^}oG}1v`OsRkwFyRmx zQNo0d_weP4wN1;Xu~B{IChD8R0+L1~$aXsPj&d^609 zl}?$I(~M_e9(&j{&BQc885ggvDI`=0?h%R~ycd{V)#M0lj=v82AbkVB+U}x@bMZ+} zii!>wQji72I<^G4s$j;3r?xzo8i*TxObljfQ0*Y#ir2&deI1i^l<#=SJCAhO-kIRl z&VwySOH#4j!w?<~VLeYptcf(H17FMUdz{@}JDL~cP`#m+Y-cV71IpnoL%<>bzEu9lsM>$dKu~8q4LG&6; zkc-$_3|_S?)k59}lU`&cKqY`YCP(H+T<0m+l<|ateVI@+DS6VS+}O1hS6gKQ)5)5P zJWX|o^T2)<_fL)|VIHxgMpKKtZdkVw$H#LSvUT{&8PhmZli)gt1>e>HM+8$0jmb>? ztiam-gWtjoW(+6VU*~T-yc^LgL?&(~(beuHhKW{3+FHH#uhVhK?sah*JD8bXL48s=O34}UhB z8;Ke2uM1$s)FQT?ehJ~11iUr6y@KtAO<6ERgJFb_gisnEu|$k}xh9-gi`>2>u^RPv87>uj4@Wpf4BZhxT*rXZY-D59$=SN#k5^ z-6^|vx^L00|B|^N3(3CM!w;QX-`#!a#6@J+OC|Hhk}=Qp)gQW9&(}P~Z9n&^qTRPy z_faHk&ysxeLGFRF5B9omu)wB3?s$T`ZG1TMOe46OCB=#4$A`J!ez0#A=Mc~#IEMqI z{FW!V8(kmlRSN6AOpF`CpPnQnd!{kG$cP(cu8?3S&6Y(y>(g%YGreys>yARo-w3bH zU;ZR_=LZ-LL3RZ_>f%<(mcJ}HZ!*|%rqAERhNI|urpLUQUF+EL})h z=!eVx>*ir6XwF;bR0=jbxj&VHO%sg%Kcrv_6l=5&H~!;X2mMcFU{7UWvpOp@gZsaJ z2KGS~Xj?%GVziKZZt-lKB=~oYXDau4D);(NHut(5x!1_u!D&n*16y(B@Vf{3$7`veAZsemda^w0*>q#9B#np48m6+Xr?Ra_ z>ir>C_pGw5Co@Uccz!SG)fF_o8hdrsREjk_=K3d|Vm)Il#rpT0Ui}c`ciTzFn}O}D ze&AHL^`CgQ^+~0)D8494k7W6Wt3PD^;hK*w|IpoWHu;CEX(YYmAZcl=tRa_Poa!4svYhH0&pD_1rgP7!-t^JtRHJO{Ip$QO7}1A1VPbxC MI_+$8s!MM8zx#vjx&QzG delta 1526 zcmZXUe^69a6vy9v_wBxYu<-U>;^%@a3#9yPmz9Mj`K1zyqF`t>iGV^=iLmKnlw!Lo zLRrq@jvk#UTa>il;xKWu#*`UzrZIC#okSrvt(-aOq_ z&z|LC21sc*4G$Rqq1H59APQ`9CVKcqJdK7em^blUA++bAMNoQOnFF`-P(#R~OU4v8 zh6f5EaPc~?r_P(oIT5a`!H>}eca&C~Y0fscb!=d3Rfov1GYT0+3%`DPf?qU_}4qJX$lX2I!d6b@^qSgG{@XZ*-YX&+O~?tXrsb#~o74g&kg`b| zO>3SagF5gxlSFE2Bu4dGaHVv-o1})(Z@bBuX1_&>g)>|DXQ*=n@$w+IlM*_)hnSEW zw};V+Ps7_$51z&hfuW&zT8m6!7_H~DV|X=M&n{s-qAr^_gACh$T^ySg74OOMSR<0+ zJ<0ns#TeqTiFoIi#`7!l?2fgqElum5hfz)PLTJwv4?}N`NGQn?7xU`eHqo&dakiwI zF8XYa*w3>!Alk$Cx%EU_P-vT5V1qsvZ=v{}aRRBb4(cz*rWeq6 z1M`|>sJRy3tU6z&{>G5#&xfK;7`d6yLSOS%dt?Y!Er?M?uTcM>ja8cdTdae!-nd1o z^Hpd%W_EykCR$G$2CMsJFzHZ8z6HunrZnmg%x5{46{Vf3d@G&lTYetV;6OqJhUum0 zB0at_`Ij&?)&(j2l5}<*tEcp#lZW8bwMS@KcWq8+?HnCRSW&8>HJj^v2o8Q5Akdb4@laR~_UafCL$$*hdPc-C?2U9H zjy8Dk01tr?IZ9)-+Y9aB@#(E}>OEq>M?WS4IQygs@V+I~(Uw8-jwZZ5f=w6+Q=Bk0 z^pfFcK^PWo8L%`)P7!UQ_-54m677hQdn9OFD96(zH=Z9ljG0{~d6&sBY*GZT7D)k4 z3b6EZ5)GVGY<83aZB-}{c4pxkxcj)Mr%8mQYT#lOGQoo!Tu8ICaR7t!5Ej8(i**p0 zi!Vc`W pEt2d-5WF0b1l|+mHZ->B1iEbw*)GyxIvLjt2MIP%Y$5j>{sreb=}iCt diff --git a/anify-backend-recode/src/content/impl/sources.ts b/anify-backend-recode/src/content/impl/sources.ts index 4a0df0c..5899d07 100644 --- a/anify-backend-recode/src/content/impl/sources.ts +++ b/anify-backend-recode/src/content/impl/sources.ts @@ -4,15 +4,15 @@ import { Source } from "../../types/types"; export const fetchSources = async (providerId: string, watchId: string, subType: SubType, server: StreamingServers): Promise => { const provider = animeProviders[providerId]; - if (!provider) return null; if (provider.subTypes && !provider.subTypes.includes(subType)) return null; try { - const data = await provider.fetchSources(watchId, subType, server).catch(() => { + const data = await provider.fetchSources(watchId, subType, server).catch((err) => { return null; }); + if (!data) return null; return data; } catch (e) { diff --git a/anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts b/anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts index 1f3dafe..3e8e10a 100644 --- a/anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts +++ b/anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts @@ -2,5 +2,12 @@ import { db } from "../.."; import { SkipTime } from "../../../types/types"; export const getSkipTimes = async (id: string): Promise => { - return (await db.query(`SELECT * FROM skipTimes WHERE id = $id`).get({ $id: id })) as SkipTime | undefined; + const data = (await db.query(`SELECT * FROM skipTimes WHERE id = $id`).get({ $id: id })) as SkipTime | undefined; + if (!data) return undefined; + + Object.assign(data, { + episodes: JSON.parse((data as any).episodes), + }); + + return data; }; diff --git a/anify-backend-recode/src/env.ts b/anify-backend-recode/src/env.ts index 7be049d..44447a4 100644 --- a/anify-backend-recode/src/env.ts +++ b/anify-backend-recode/src/env.ts @@ -10,6 +10,7 @@ export const env = { API_KEY_WHITELIST: process.env.API_KEY_WHITELIST?.split(",") || [], CENSYS_ID: process.env.CENSYS_ID, CENSYS_SECRET: process.env.CENSYS_SECRET, + SIMKL_CLIENT_ID: process.env.SIMKL_CLIENT_ID, USE_MIXDROP: process.env.USE_MIXDROP === "true" || false, MIXDROP_EMAIL: process.env.MIXDROP_EMAIL, MIXDROP_KEY: process.env.MIXDROP_KEY, diff --git a/anify-backend-recode/src/lib/impl/skipTimes.ts b/anify-backend-recode/src/lib/impl/skipTimes.ts index 34e9202..7611800 100644 --- a/anify-backend-recode/src/lib/impl/skipTimes.ts +++ b/anify-backend-recode/src/lib/impl/skipTimes.ts @@ -32,7 +32,7 @@ export const loadSkipTimes = async (data: { id: string; episode: number; toInser } if (data.toInsert.intro.end > 0 || data.toInsert.outro.end > 0) { - toInsert.episodes.push({ + toInsert?.episodes.push({ intro: data.toInsert.intro, outro: data.toInsert.outro, number: data.episode, diff --git a/anify-backend-recode/src/mappings/impl/anime/animepahe.ts b/anify-backend-recode/src/mappings/impl/anime/animepahe.ts index 775d3a7..74d1653 100644 --- a/anify-backend-recode/src/mappings/impl/anime/animepahe.ts +++ b/anify-backend-recode/src/mappings/impl/anime/animepahe.ts @@ -162,7 +162,7 @@ export default class AnimePahe extends AnimeProvider { headers: this.headers ?? {}, }; - return await new Extractor(matches[0], result).extract(server); + return await new Extractor(matches[0], result).extract(server ?? StreamingServers.Kwik); } catch (e) { console.error(e); return undefined; diff --git a/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts b/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts index bf58e36..6e75976 100644 --- a/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts +++ b/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts @@ -103,7 +103,7 @@ export default class GogoAnime extends AnimeProvider { const serverURL = id; const download = `https://gogohd.net/download${new URL(serverURL).search}`; - return await new Extractor(serverURL, result).extract(server); + return await new Extractor(serverURL, result).extract(server ?? StreamingServers.GogoCDN); } const data = await (await this.request(`${this.url}${id}`)).text(); @@ -127,6 +127,6 @@ export default class GogoAnime extends AnimeProvider { break; } - return await this.fetchSources(serverURL, subType, server); + return await this.fetchSources(serverURL, subType, server ?? StreamingServers.GogoCDN); } } diff --git a/anify-backend-recode/src/mappings/impl/anime/nineanime.ts b/anify-backend-recode/src/mappings/impl/anime/nineanime.ts index d6c7264..1008604 100644 --- a/anify-backend-recode/src/mappings/impl/anime/nineanime.ts +++ b/anify-backend-recode/src/mappings/impl/anime/nineanime.ts @@ -138,7 +138,7 @@ export default class NineAnime extends AnimeProvider { const source = (await (await this.request(`${this.resolver}/decrypt?query=${encodeURIComponent(serverSource.result?.url)}&apikey=${this.resolverKey}`)).json()).url.split("/").pop(); - return await new Extractor(source, result).extract(server); + return await new Extractor(source, result).extract(server ?? StreamingServers.MyCloud); } if (subType === SubType.SUB) { @@ -170,10 +170,12 @@ export default class NineAnime extends AnimeProvider { if (!s) throw new Error("Filemoon server found"); break; default: - throw new Error("Server not found"); + s = servers.find((s) => s.name === "vidstream")!; + if (!s) throw new Error("Vidstream server found"); + break; } - return await this.fetchSources(s.url, subType, server); + return await this.fetchSources(s.url, subType, server ?? StreamingServers.MyCloud); } override async fetchServers(id: string): Promise { diff --git a/anify-backend-recode/src/mappings/impl/anime/zoro.ts b/anify-backend-recode/src/mappings/impl/anime/zoro.ts index 94d0bb8..dd7ac84 100644 --- a/anify-backend-recode/src/mappings/impl/anime/zoro.ts +++ b/anify-backend-recode/src/mappings/impl/anime/zoro.ts @@ -112,7 +112,7 @@ export default class Zoro extends AnimeProvider { if (id.startsWith("http")) { const serverURL = id; - return await new Extractor(serverURL, result).extract(server); + return await new Extractor(serverURL, result).extract(server ?? StreamingServers.VidCloud); } const data = await (await this.request(`${this.url}/ajax/v2/episode/servers?episodeId=${id.split("?ep=")[1]}`)).json(); @@ -147,11 +147,14 @@ export default class Zoro extends AnimeProvider { if (!serverId) throw new Error("StreamTape not found"); break; default: - throw new Error("Server not found"); + serverId = this.retrieveServerId($, 4, subType); + + if (!serverId) throw new Error("RapidCloud not found"); + break; } const req = await (await this.request(`${this.url}/ajax/v2/episode/sources?id=${serverId}`)).json(); - return await this.fetchSources(req.link, subType, server); + return await this.fetchSources(req.link, subType, server ?? StreamingServers.VidCloud); } private retrieveServerId($: any, index: number, subOrDub: SubType) { diff --git a/anify-backend-recode/src/server/impl/episodeCovers.ts b/anify-backend-recode/src/server/impl/episodeCovers.ts new file mode 100644 index 0000000..fe17415 --- /dev/null +++ b/anify-backend-recode/src/server/impl/episodeCovers.ts @@ -0,0 +1,75 @@ +import { get } from "../../database/impl/modify/get"; +import { env } from "../../env"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const id = body?.id ?? paths[1] ?? url.searchParams.get("id") ?? null; + if (!id) { + return new Response(JSON.stringify({ error: "No ID provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const simklClientId = env.SIMKL_CLIENT_ID; + + if (!simklClientId) + return new Response(JSON.stringify({ error: "No SIMKL credentials provided." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + + const episodeCovers: { episode: number; img: string }[] = []; + + const media = await get(id); + if (!media) + return new Response(JSON.stringify({ error: "Media not found." }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + + const aniListId = media.mappings.find((mapping) => mapping.providerId === "anilist")?.id; + + const searchQuery = await (await fetch(`https://api.simkl.com/search/id?anilist=${aniListId}&client_id=${simklClientId}`)).json(); + const simklId = searchQuery[0]?.ids?.simkl; + + const data = await (await fetch(`https://api.simkl.com/anime/episodes/${simklId}?client_id=${simklClientId}`)).json(); + + for (const episode of data) { + if (!episode.img) continue; + episodeCovers.push({ + episode: episode.episode, + img: `https://simkl.in/episodes/${episode.img}_c.jpg`, + }); + } + + return new Response(JSON.stringify(episodeCovers), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + path: "/episode-covers", + handler, +}; + +export default route; diff --git a/anify-backend-recode/src/server/impl/sources.ts b/anify-backend-recode/src/server/impl/sources.ts index 05a0f1c..36c48fc 100644 --- a/anify-backend-recode/src/server/impl/sources.ts +++ b/anify-backend-recode/src/server/impl/sources.ts @@ -60,9 +60,15 @@ export const handler = async (req: Request): Promise => { }); } - const server = decodeURIComponent(body.server ?? paths[6] ?? url.searchParams.get("server") ?? "") as StreamingServers; + const server = body.server ?? paths[6] ?? url.searchParams.get("server") ?? undefined ? (decodeURIComponent(body.server ?? paths[6] ?? url.searchParams.get("server") ?? undefined) as StreamingServers) : undefined; - const data = await content.fetchSources(providerId, watchId, subType.toUpperCase() as SubType, server); + const data = await content.fetchSources(providerId, watchId, subType as SubType, server as StreamingServers); + + if (!data) + return new Response(JSON.stringify({ error: "Sources not found." }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); if (data) queues.skipTimes.add({ id, episode: episodeNumber, toInsert: data }); diff --git a/anify-frontend/src/pages/watch/[id]/[provider]/[watchId]/[subDub].tsx b/anify-frontend/src/pages/watch/[id]/[provider]/[watchId]/[subDub].tsx index 467aeea..3d10c29 100644 --- a/anify-frontend/src/pages/watch/[id]/[provider]/[watchId]/[subDub].tsx +++ b/anify-frontend/src/pages/watch/[id]/[provider]/[watchId]/[subDub].tsx @@ -870,8 +870,9 @@ export const getServerSideProps: GetServerSideProps = async (context) => { providerId: provider, watchId: watchId, subType: subDub, - episode: episodeNumber > 0 ? episodeNumber : -1 + episodeNumber: episodeNumber > 0 ? episodeNumber : -1 }).catch((err) => { + console.error(err); return { data: { sources: [], From bab53237e4746764d2c9e9ef538583b539ca849e Mon Sep 17 00:00:00 2001 From: Eltik Date: Sat, 9 Sep 2023 19:23:48 -0400 Subject: [PATCH 25/77] Fix MangaDex and seasonal route --- anify-backend-recode/db.sqlite | Bin 5648384 -> 5808128 bytes .../src/database/impl/misc/seasonal.ts | 8 +- .../src/mappings/impl/base/mangadex.ts | 86 ++++++++++++++++++ anify-frontend/src/helper/index.ts | 2 +- anify-frontend/src/pages/info/[id].tsx | 8 +- anify-frontend/src/pages/manga.tsx | 2 +- anify-frontend/src/pages/novels.tsx | 2 +- 7 files changed, 97 insertions(+), 11 deletions(-) diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 4de563ba0224c8fc9c4453adc44df2ef2192ea2a..9234e9b8754ff51bfd12b0f8dc7a415fa8822107 100644 GIT binary patch delta 377720 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 {L`5CBG}l|d`Un1v`)Kyj#3+W?^iRdvO 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%0Db33 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

;% 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 delta 19373 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 diff --git a/anify-backend-recode/src/database/impl/misc/seasonal.ts b/anify-backend-recode/src/database/impl/misc/seasonal.ts index 8d2bac0..01a963f 100644 --- a/anify-backend-recode/src/database/impl/misc/seasonal.ts +++ b/anify-backend-recode/src/database/impl/misc/seasonal.ts @@ -60,19 +60,19 @@ export const seasonal = async (trending: AnimeInfo[] | MangaInfo[], popular: Ani // Fetch media for each category const [trend, pop, t, season] = await Promise.all([ fetchMediaByType( - trending[0].type, + trending[0]?.type, trending.map((a) => String(a.id)), ), fetchMediaByType( - popular[0].type, + popular[0]?.type, popular.map((a) => String(a.id)), ), fetchMediaByType( - top[0].type, + top[0]?.type, top.map((a) => String(a.id)), ), fetchMediaByType( - seasonal[0].type, + seasonal[0]?.type, seasonal.map((a) => String(a.id)), ), ]); diff --git a/anify-backend-recode/src/mappings/impl/base/mangadex.ts b/anify-backend-recode/src/mappings/impl/base/mangadex.ts index 1dd52fd..281da80 100644 --- a/anify-backend-recode/src/mappings/impl/base/mangadex.ts +++ b/anify-backend-recode/src/mappings/impl/base/mangadex.ts @@ -287,4 +287,90 @@ export default class ManagDexBase extends BaseProvider { return undefined; } } + + override async fetchSeasonal(type: Type, formats: Format[]): Promise<{ trending: AnimeInfo[] | MangaInfo[]; seasonal: AnimeInfo[] | MangaInfo[]; popular: AnimeInfo[] | MangaInfo[]; top: AnimeInfo[] | MangaInfo[] } | undefined> { + const currentDate = new Date(); + + // Format the date as YYYY-MM-DD + const year = currentDate.getFullYear(); + const month = String(currentDate.getMonth() + 1).padStart(2, "0"); // Months are zero-based + const day = String(currentDate.getDate()).padStart(2, "0"); + const createdAtParam = `${year}-${month}-${day}T00:00:00`; + + const trending = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&order[followedCount]=desc&contentRating[]=safe&contentRating[]=suggestive&hasAvailableChapters=true&createdAtSince=${createdAtParam}`, {}, true)).json(); + const popular = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&order[followedCount]=desc&contentRating[]=safe&contentRating[]=suggestive&hasAvailableChapters=true`, {}, true)).json(); + const top = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&order[rating]=desc&contentRating[]=safe&contentRating[]=suggestive&hasAvailableChapters=true`, {}, true)).json(); + const seasonalReq = await (await this.request(`${this.api}/list/1b9f88f8-9880-464d-9ed9-59b7e36392e2?includes[]=user`, {}, true)).json(); + + const seasonalIDs: string[] = []; + for (const item of seasonalReq.data.relationships) { + if (item.type === "manga") { + seasonalIDs.push(item.id); + } + } + const seasonal = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&ids[]=${seasonalIDs.join("&ids[]=")}`, {}, true)).json(); + + const trendingList: MangaInfo[] = []; + const popularList: MangaInfo[] = []; + const topList: MangaInfo[] = []; + const seasonalList: MangaInfo[] = []; + + for (const manga of trending.data) { + trendingList.push(this.returnFilledManga(manga)); + } + + for (const manga of popular.data) { + popularList.push(this.returnFilledManga(manga)); + } + + for (const manga of top.data) { + topList.push(this.returnFilledManga(manga)); + } + + for (const manga of seasonal.data) { + seasonalList.push(this.returnFilledManga(manga)); + } + + return { + trending: trendingList, + seasonal: seasonalList, + popular: popularList, + top: topList, + }; + } + + private returnFilledManga(manga: any) { + const formatString: string = manga.type.toUpperCase(); + const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; + + return { + id: manga.id, + type: Type.MANGA, + title: { + english: manga.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "en")?.en ?? null, + romaji: manga.attributes.title["ja-ro"] ?? manga.attributes.title["jp-ro"] ?? manga.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja-ro")?.["ja-ro"] ?? manga.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp-ro")?.["jp-ro"] ?? null, + native: manga.attributes.title["jp"] ?? manga.attributes.title["ja"] ?? manga.attributes.title["ko"] ?? manga.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "jp")?.jp ?? manga.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ja")?.ja ?? manga.attributes.altTitles.find((title: { [key: string]: string }) => Object.keys(title)[0] === "ko")?.ko ?? null, + }, + synonyms: manga.attributes.altTitles.map((title: { [key: string]: string }) => { + return Object.values(title)[0]; + }), + description: manga.attributes.description.en ?? manga.attributes.description.jp ?? manga.attributes.description.jp_ro ?? manga.attributes.description.ko ?? Object.values(manga.attributes.description)[0], + countryOfOrigin: manga.attributes.publicationDemographic ?? manga.attributes.originalLanguage?.toUpperCase() ?? null, + characters: [], + genres: manga.attributes.tags.filter((tag: any) => tag.attributes.group === "genre").map((tag: any) => tag.attributes.name.en), + year: manga.attributes.year, + artwork: [], + totalChapters: manga.attributes.lastChapter ?? null, + totalVolumes: manga.attributes.lastVolume ?? null, + status: manga.attributes.status === "ongoing" ? MediaStatus.RELEASING : manga.attributes.status === "completed" ? MediaStatus.FINISHED : null, + color: null, + popularity: null, + relations: [], + tags: manga.attributes.tags.filter((tag: any) => tag.attributes.group === "theme").map((tag: any) => tag.attributes.name.en), + rating: null, + format, + coverImage: `${this.url}/covers/${manga.id}/${manga.relationships.find((element: any) => element.type === "cover_art").id}.jpg`, + bannerImage: null, + }; + } } diff --git a/anify-frontend/src/helper/index.ts b/anify-frontend/src/helper/index.ts index d437e93..2c8bde0 100644 --- a/anify-frontend/src/helper/index.ts +++ b/anify-frontend/src/helper/index.ts @@ -1,7 +1,7 @@ import { Format, MediaStatus } from "~/types"; export function capitalize(s: string) { - s = s.toLowerCase(); + s = s?.toLowerCase(); return s && (s[0]?.toUpperCase() ?? "") + s.slice(1); } diff --git a/anify-frontend/src/pages/info/[id].tsx b/anify-frontend/src/pages/info/[id].tsx index 5b38d34..30fae34 100644 --- a/anify-frontend/src/pages/info/[id].tsx +++ b/anify-frontend/src/pages/info/[id].tsx @@ -365,25 +365,25 @@ const Info: NextPage = ({ media, relations, content }) => { boxShadow: "0 1px 12px #000a" }}>

- {media.rating.anilist && media.rating.anilist != 0 ? ( + {media.rating?.anilist && media.rating.anilist != 0 ? (
AniList {media.rating.anilist}
) : null} - {media.rating.mal && media.rating.mal != 0 ? ( + {media.rating?.mal && media.rating.mal != 0 ? (
MAL {media.rating.mal}
) : null} - {media.rating.kitsu && media.rating.kitsu != 0 ? ( + {media.rating?.kitsu && media.rating.kitsu != 0 ? (
Kitsu {media.rating.kitsu}
) : null} - {media.rating.simkl && media.rating.simkl != 0 ? ( + {media.rating?.simkl && media.rating.simkl != 0 ? (
Simkl {media.rating.simkl} diff --git a/anify-frontend/src/pages/manga.tsx b/anify-frontend/src/pages/manga.tsx index deb45e2..ab0c628 100644 --- a/anify-frontend/src/pages/manga.tsx +++ b/anify-frontend/src/pages/manga.tsx @@ -140,7 +140,7 @@ const Manga: NextPage = ({ seasonal, recent }) => { }; export const getServerSideProps: GetServerSideProps = async () => { - const seasonal = (await axios.get(String(env.BACKEND_URL) + "/seasonal/manga?apikey=" + String(env.API_KEY))).data as Seasonal; + const seasonal = (await axios.get(String(env.BACKEND_URL) + "/seasonal?type=manga&fields=[id,description,bannerImage,coverImage,title,genres,format,averageRating,episodes,chapters,year]&apikey=" + String(env.API_KEY))).data as Seasonal; const recent = (await axios.get(String(env.BACKEND_URL) + "/recent?type=manga&apikey=" + String(env.API_KEY))).data as Manga[]; return { diff --git a/anify-frontend/src/pages/novels.tsx b/anify-frontend/src/pages/novels.tsx index 175c49c..95f536a 100644 --- a/anify-frontend/src/pages/novels.tsx +++ b/anify-frontend/src/pages/novels.tsx @@ -142,7 +142,7 @@ const Novel: NextPage = ({ seasonal, recent }) => { }; export const getServerSideProps: GetServerSideProps = async () => { - const seasonal = (await axios.get(String(env.BACKEND_URL) + "/seasonal/novel?apikey=" + String(env.API_KEY))).data as Seasonal; + const seasonal = (await axios.get(String(env.BACKEND_URL) + "/seasonal?type=novel&fields=[id,description,bannerImage,coverImage,title,genres,format,averageRating,episodes,chapters,year]&apikey=" + String(env.API_KEY))).data as Seasonal; const recent = (await axios.get(String(env.BACKEND_URL) + "/recent?type=novel&apikey=" + String(env.API_KEY))).data as Manga[]; return { From 20ac584224d8a09cf91d67ed69f0637145244bd6 Mon Sep 17 00:00:00 2001 From: Eltik Date: Sun, 10 Sep 2023 11:29:48 -0400 Subject: [PATCH 26/77] Fix __dirname --- anify-backend-recode/src/server/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anify-backend-recode/src/server/index.ts b/anify-backend-recode/src/server/index.ts index 121f9fc..46a2dde 100644 --- a/anify-backend-recode/src/server/index.ts +++ b/anify-backend-recode/src/server/index.ts @@ -20,9 +20,9 @@ export const start = async () => { if (url.pathname === "/") return new Response("Welcome to Anify API! 🎉 Documentation can be viewed at https://docs.anify.tv. Join our Discord https://anify.tv/discord for more information.", { headers: { "Content-Type": "application/json" } }); // Dynamically add routes - const routeFiles = readdirSync(join(__dirname, "./impl")); + const routeFiles = readdirSync(join(import.meta.dir, "./impl")); for (const file of routeFiles) { - const routeModule = await import(join(__dirname, "./impl", file)); + const routeModule = await import(join(import.meta.dir, "./impl", file)); const route = routeModule.default; if (route) { From 9ee1ea3366d2c80fad5875da55fe9419b85e7038 Mon Sep 17 00:00:00 2001 From: Eltik Date: Mon, 11 Sep 2023 11:02:18 -0400 Subject: [PATCH 27/77] Bug fixes to MangaDex --- anify-backend-recode/db.sqlite | Bin 5808128 -> 5808128 bytes anify-backend-recode/src/index.ts | 1 + anify-backend-recode/src/lib/impl/pdf.ts | 11 ++++--- anify-backend-recode/src/lib/index.ts | 2 +- .../src/mappings/impl/base/mangadex.ts | 30 +++++++++++++++--- .../src/mappings/impl/manga/mangadex.ts | 2 -- anify-backend-recode/src/server/impl/pages.ts | 30 ++++++++++++++++-- anify-backend-recode/src/server/index.ts | 30 ++++++++++-------- anify-backend-recode/src/worker/impl/pdf.ts | 14 ++++++++ anify-backend-recode/src/worker/index.ts | 2 ++ .../pages/read/[id]/[provider]/[readId].tsx | 30 ++++++++++-------- 11 files changed, 111 insertions(+), 41 deletions(-) create mode 100644 anify-backend-recode/src/worker/impl/pdf.ts diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 9234e9b8754ff51bfd12b0f8dc7a415fa8822107..edab2ce267e797772077261dd3cf523da818ea21 100644 GIT binary patch delta 26482 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 ah1W(oZIo3wrR^IHwlg;1Xz>2Xj=uqi>2;z2 diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts index 89501fa..bb42f88 100644 --- a/anify-backend-recode/src/index.ts +++ b/anify-backend-recode/src/index.ts @@ -76,4 +76,5 @@ async function before() { queues.searchQueue.start(); queues.seasonalQueue.start(); queues.skipTimes.start(); + queues.uploadPages.start(); } diff --git a/anify-backend-recode/src/lib/impl/pdf.ts b/anify-backend-recode/src/lib/impl/pdf.ts index c780e2c..1bcfb70 100644 --- a/anify-backend-recode/src/lib/impl/pdf.ts +++ b/anify-backend-recode/src/lib/impl/pdf.ts @@ -9,18 +9,20 @@ import { pipeline } from "node:stream"; import { promisify } from "node:util"; import imageSize from "image-size"; import { env } from "../../env"; +import emitter, { Events } from ".."; -export const loadPDF = async (providerId: string, chapter: Chapter, pages: string | Page[]): Promise => { +export const loadPDF = async (data: { providerId: string; chapter: Chapter; pages: string | Page[] }): Promise => { const useMixdrop = env.USE_MIXDROP; if (!useMixdrop) return; - if (typeof pages === "string") { - return await createNovelPDF(providerId, chapter, pages); + if (typeof data.pages === "string") { + return await createNovelPDF(data.providerId, data.chapter, data.pages); } - return await createMangaPDF(providerId, chapter, pages); + return await createMangaPDF(data.providerId, data.chapter, data.pages); }; export const createNovelPDF = async (providerId: string, chapter: Chapter, pages: string): Promise => { + await emitter.emitAsync(Events.COMPLETED_PAGES_UPLOAD, ""); return ""; }; @@ -123,6 +125,7 @@ export const createMangaPDF = async (providerId: string, chapter: Chapter, pages } } + await emitter.emitAsync(Events.COMPLETED_PAGES_UPLOAD, `${parentFolder}/${chapter.title.replace(/[^\w .-]/gi, "")}.pdf`); return `${parentFolder}/${chapter.title.replace(/[^\w .-]/gi, "")}.pdf`; }; diff --git a/anify-backend-recode/src/lib/index.ts b/anify-backend-recode/src/lib/index.ts index f2c61a2..2e0b8d4 100644 --- a/anify-backend-recode/src/lib/index.ts +++ b/anify-backend-recode/src/lib/index.ts @@ -6,7 +6,7 @@ export enum Events { COMPLETED_SEARCH_LOAD = "search.load.completed", COMPLETED_SEASONAL_LOAD = "seasonal.load.completed", COMPLETED_ENTRY_CREATION = "entry.creation.completed", - COMPLETED_PAGE_UPLOAD = "page.upload.completed", + COMPLETED_PAGES_UPLOAD = "page.upload.completed", } const emitter = new EventEmitter2({}); diff --git a/anify-backend-recode/src/mappings/impl/base/mangadex.ts b/anify-backend-recode/src/mappings/impl/base/mangadex.ts index 281da80..a31f457 100644 --- a/anify-backend-recode/src/mappings/impl/base/mangadex.ts +++ b/anify-backend-recode/src/mappings/impl/base/mangadex.ts @@ -297,10 +297,26 @@ export default class ManagDexBase extends BaseProvider { const day = String(currentDate.getDate()).padStart(2, "0"); const createdAtParam = `${year}-${month}-${day}T00:00:00`; - const trending = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&order[followedCount]=desc&contentRating[]=safe&contentRating[]=suggestive&hasAvailableChapters=true&createdAtSince=${createdAtParam}`, {}, true)).json(); - const popular = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&order[followedCount]=desc&contentRating[]=safe&contentRating[]=suggestive&hasAvailableChapters=true`, {}, true)).json(); - const top = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&order[rating]=desc&contentRating[]=safe&contentRating[]=suggestive&hasAvailableChapters=true`, {}, true)).json(); - const seasonalReq = await (await this.request(`${this.api}/list/1b9f88f8-9880-464d-9ed9-59b7e36392e2?includes[]=user`, {}, true)).json(); + const trending = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&order[followedCount]=desc&contentRating[]=safe&contentRating[]=suggestive&hasAvailableChapters=true&createdAtSince=${createdAtParam}`, {}, true)).json().catch(() => { + return { + data: [], + }; + }); + const popular = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&order[followedCount]=desc&contentRating[]=safe&contentRating[]=suggestive&hasAvailableChapters=true`, {}, true)).json().catch(() => { + return { + data: [], + }; + }); + const top = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&order[rating]=desc&contentRating[]=safe&contentRating[]=suggestive&hasAvailableChapters=true`, {}, true)).json().catch(() => { + return { + data: [], + }; + }); + const seasonalReq = await (await this.request(`${this.api}/list/1b9f88f8-9880-464d-9ed9-59b7e36392e2?includes[]=user`, {}, true)).json().catch(() => { + return { + data: [], + }; + }); const seasonalIDs: string[] = []; for (const item of seasonalReq.data.relationships) { @@ -308,7 +324,11 @@ export default class ManagDexBase extends BaseProvider { seasonalIDs.push(item.id); } } - const seasonal = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&ids[]=${seasonalIDs.join("&ids[]=")}`, {}, true)).json(); + const seasonal = await (await this.request(`${this.api}/manga?includes[]=cover_art&includes[]=artist&includes[]=author&ids[]=${seasonalIDs.join("&ids[]=")}`, {}, true)).json().catch(() => { + return { + data: [], + }; + }); const trendingList: MangaInfo[] = []; const popularList: MangaInfo[] = []; diff --git a/anify-backend-recode/src/mappings/impl/manga/mangadex.ts b/anify-backend-recode/src/mappings/impl/manga/mangadex.ts index 6ac2b47..7461051 100644 --- a/anify-backend-recode/src/mappings/impl/manga/mangadex.ts +++ b/anify-backend-recode/src/mappings/impl/manga/mangadex.ts @@ -25,8 +25,6 @@ export default class MangaDex extends MangaProvider { uri.searchParams.set("order[relevance]", "desc"); uri.searchParams.append("contentRating[]", "safe"); uri.searchParams.append("contentRating[]", "suggestive"); - uri.searchParams.append("contentRating[]", "erotica"); - uri.searchParams.append("contentRating[]", "pornographic"); uri.searchParams.append("includes[]", "cover_art"); const data = await (await this.request(uri.href)).json(); diff --git a/anify-backend-recode/src/server/impl/pages.ts b/anify-backend-recode/src/server/impl/pages.ts index 6da574d..7f3184a 100644 --- a/anify-backend-recode/src/server/impl/pages.ts +++ b/anify-backend-recode/src/server/impl/pages.ts @@ -1,4 +1,6 @@ import content from "../../content"; +import { Chapter, Page } from "../../types/types"; +import queues from "../../worker"; export const handler = async (req: Request): Promise => { try { @@ -13,7 +15,23 @@ export const handler = async (req: Request): Promise => { }) : null; - const providerId = body?.providerId ?? paths[1] ?? url.searchParams.get("providerId") ?? null; + const chapterTitle = body.chapterTitle ?? paths[1] ?? url.searchParams.get("chapterTitle") ?? null; + if (!chapterTitle) { + return new Response(JSON.stringify({ error: "No chapter title provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const chapterNumber = Number(body.chapterNumber ?? paths[2] ?? url.searchParams.get("chapterNumber") ?? null); + if (!chapterNumber) { + return new Response(JSON.stringify({ error: "No chapter number provided." }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } + + const providerId = body?.providerId ?? paths[3] ?? url.searchParams.get("providerId") ?? null; if (!providerId) { return new Response(JSON.stringify({ error: "No provider ID provided." }), { status: 400, @@ -21,7 +39,7 @@ export const handler = async (req: Request): Promise => { }); } - const readId = decodeURIComponent(body?.readId ?? paths[2] ?? url.searchParams.get("readId") ?? ""); + const readId = decodeURIComponent(body?.readId ?? paths[4] ?? url.searchParams.get("readId") ?? ""); if (!readId || readId.length === 0) { return new Response(JSON.stringify({ error: "No read ID provided." }), { status: 400, @@ -31,6 +49,14 @@ export const handler = async (req: Request): Promise => { const data = await content.fetchPages(providerId, readId); + const chapter: Chapter | null = { + id: readId, + number: chapterNumber, + title: chapterTitle, + }; + + if (chapter) await queues.uploadPages.add({ providerId, chapter, pages: (data as Page[] | string) ?? [] }); + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/index.ts b/anify-backend-recode/src/server/index.ts index 46a2dde..0c6ae4c 100644 --- a/anify-backend-recode/src/server/index.ts +++ b/anify-backend-recode/src/server/index.ts @@ -10,29 +10,31 @@ import { env } from "../env"; export const start = async () => { const redis = new Redis((env.REDIS_URL as string) || "redis://localhost:6379"); const cacheTime = env.REDIS_CACHE_TIME; - const whitelist = env.API_KEY_WHITELIST; + const routes: { [key: string]: { path: string; handler: (req: Request) => Promise } } = {}; + const routeFiles = readdirSync(join(import.meta.dir, "./impl")); + for (const file of routeFiles) { + const routeModule = await import(join(import.meta.dir, "./impl", file)); + const route = routeModule.default; + + if (route) { + const { path, handler } = route; + routes[path] = { path, handler }; + } + } + Bun.serve({ port: env.PORT, async fetch(req: Request) { const url = new URL(req.url); if (url.pathname === "/") return new Response("Welcome to Anify API! 🎉 Documentation can be viewed at https://docs.anify.tv. Join our Discord https://anify.tv/discord for more information.", { headers: { "Content-Type": "application/json" } }); - // Dynamically add routes - const routeFiles = readdirSync(join(import.meta.dir, "./impl")); - for (const file of routeFiles) { - const routeModule = await import(join(import.meta.dir, "./impl", file)); - const route = routeModule.default; - - if (route) { - const { path, handler } = route; - const pathName = url.pathname.split("/").slice(1)[0]; + const pathName = `/${url.pathname.split("/").slice(1)[0]}`; - if (path === `/${pathName}`) { - return handler(req); - } - } + if (routes[pathName]) { + const { path, handler } = routes[pathName]; + return handler(req); } return new Response(JSON.stringify({ error: "Route not found" }), { status: 404, headers: { "Content-Type": "application/json" } }); diff --git a/anify-backend-recode/src/worker/impl/pdf.ts b/anify-backend-recode/src/worker/impl/pdf.ts new file mode 100644 index 0000000..4fa0e84 --- /dev/null +++ b/anify-backend-recode/src/worker/impl/pdf.ts @@ -0,0 +1,14 @@ +import colors from "colors"; +import QueueExecutor from "../../lib/executor"; +import { Chapter, Page } from "../../types/types"; +import { loadPDF } from "../../lib/impl/pdf"; + +const executor = new QueueExecutor<{ providerId: string; chapter: Chapter; pages: string | Page[] }>("page-upload-executor") + .executor(async (data) => { + const media = await loadPDF(data); + return media; + }) + .callback((id) => console.debug(colors.green(`Finished uploading pages for ${id.chapter.id}.`))) + .error((err, id) => console.error(colors.red(`Error occurred while uploading pages for ${id.chapter.id}`), err)) + .interval(1000); +export default executor; diff --git a/anify-backend-recode/src/worker/index.ts b/anify-backend-recode/src/worker/index.ts index 0b31fe4..9331c6d 100644 --- a/anify-backend-recode/src/worker/index.ts +++ b/anify-backend-recode/src/worker/index.ts @@ -3,6 +3,7 @@ import createEntry from "./impl/entry"; import searchQueue from "./impl/search"; import seasonalQueue from "./impl/seasonal"; import skipTimes from "./impl/skipTimes"; +import uploadPages from "./impl/pdf"; export default { mappingQueue, @@ -10,4 +11,5 @@ export default { searchQueue, seasonalQueue, skipTimes, + uploadPages, }; diff --git a/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx b/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx index 32ce547..56c1fdd 100644 --- a/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx +++ b/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx @@ -532,11 +532,6 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const media = (await axios.get(String(env.BACKEND_URL) + "/info/" + String(id) + "?apikey=" + String(env.API_KEY))).data as Manga; const content = (await axios.get(String(env.BACKEND_URL) + "/chapters/" + String(id) + "?apikey=" + String(env.API_KEY))).data as ChapterData[]; - const pages = await (await axios.post(String(env.BACKEND_URL) + "/pages?apikey=" + String(env.API_KEY), { - id, - providerId: provider, - readId - })).data as Page[]; let mixdrop = ""; for (const prov of content) { @@ -555,19 +550,12 @@ export const getServerSideProps: GetServerSideProps = async (context) => { })).data as MixdropResponse; } - if (media.format !== "NOVEL") { - for (let i = 0; i < pages.length; i++) { - if (pages[i]?.headers && Object.keys(pages[i]?.headers ?? {}).length > 0) { - Object.assign(pages[i] ?? {}, { url: `${String(env.IMAGE_PROXY)}?url=${encodeURIComponent(String(pages[i]?.url))}&headers=${encodeURIComponent(JSON.stringify(pages[i]?.headers))}` }) - } - } - } - content.reverse(); let nextChapter = ""; let previousChapter = ""; let chapterNumber = -1; + let chapterTitle = ""; const chapterSelector = []; @@ -577,6 +565,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const chapter = providerChap?.chapters[j]; if (chapter?.id === readId) { + chapterTitle = chapter?.title ?? ""; chapterNumber = chapter.number ?? i; } if (providerChap?.providerId.toLowerCase() === (provider as string).toLowerCase()) { @@ -612,6 +601,21 @@ export const getServerSideProps: GetServerSideProps = async (context) => { } } + const pages = await (await axios.post(String(env.BACKEND_URL) + "/pages?apikey=" + String(env.API_KEY), { + chapterNumber, + chapterTitle, + providerId: provider, + readId + })).data as Page[]; + + if (media.format !== "NOVEL") { + for (let i = 0; i < pages.length; i++) { + if (pages[i]?.headers && Object.keys(pages[i]?.headers ?? {}).length > 0) { + Object.assign(pages[i] ?? {}, { url: `${String(env.IMAGE_PROXY)}?url=${encodeURIComponent(String(pages[i]?.url))}&headers=${encodeURIComponent(JSON.stringify(pages[i]?.headers))}` }) + } + } + } + return { props: { media, From b2f05c1532005ba37bf577d5286f0dc3447a0469 Mon Sep 17 00:00:00 2001 From: Eltik Date: Mon, 11 Sep 2023 11:25:19 -0400 Subject: [PATCH 28/77] Add redis caching --- anify-backend-recode/db.sqlite | Bin 5808128 -> 5808128 bytes .../src/server/impl/chapters.ts | 11 +++++++++++ .../src/server/impl/episodeCovers.ts | 11 +++++++++++ .../src/server/impl/episodes.ts | 11 +++++++++++ anify-backend-recode/src/server/impl/info.ts | 11 +++++++++++ anify-backend-recode/src/server/impl/pages.ts | 11 +++++++++++ .../src/server/impl/recent.ts | 11 +++++++++++ .../src/server/impl/relations.ts | 11 +++++++++++ .../src/server/impl/search.ts | 16 +++++++++++----- .../src/server/impl/searchAdvanced.ts | 16 +++++++++++----- .../src/server/impl/seasonal.ts | 11 +++++++++++ .../src/server/impl/sources.ts | 11 +++++++++++ anify-backend-recode/src/server/impl/stats.ts | 11 +++++++++++ anify-backend-recode/src/server/index.ts | 15 +++++++++++---- 14 files changed, 143 insertions(+), 14 deletions(-) diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index edab2ce267e797772077261dd3cf523da818ea21..39d7e1c39a0026849e91a0221df4ee52ce29c1db 100644 GIT binary patch delta 172152 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

)Xh0AX0Pgy0(wZhG+qxlzF)56DX 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

Providers


- {providers.map((p, index) => ( + {providers?.map((p, index) => (
{p.name} diff --git a/anify-manager/package.json b/anify-manager/package.json index 9fae23f..102bc54 100644 --- a/anify-manager/package.json +++ b/anify-manager/package.json @@ -21,6 +21,7 @@ }, "dependencies": { "colors": "^1.4.0", - "eris": "^0.17.2" + "eris": "^0.17.2", + "pm2": "^5.3.0" } } \ No newline at end of file diff --git a/anify-manager/src/config.ts b/anify-manager/src/config.ts index c954752..03e0523 100644 --- a/anify-manager/src/config.ts +++ b/anify-manager/src/config.ts @@ -5,7 +5,7 @@ export const buildCommands: { }; } = { anify: { - command: "npm run build", + command: "npm run install && npm run lint && npm run build", ".env": `.env`, }, }; diff --git a/anify-manager/src/discord/client.ts b/anify-manager/src/discord/client.ts index 62118a6..c8d685f 100644 --- a/anify-manager/src/discord/client.ts +++ b/anify-manager/src/discord/client.ts @@ -46,7 +46,7 @@ client.on("ready", async () => { readdirSync(join(import.meta.dir, "./commands")).forEach((file) => { // check if file is a folder (if it is make it a subcommand) if (lstatSync(join(import.meta.dir, `./commands/${file}`)).isDirectory()) { - let subcommands: ApplicationCommand[] = []; + const subcommands: ApplicationCommand[] = []; readdirSync(join(import.meta.dir, `./commands/${file}`)).forEach((subfile) => { const command = require(`./commands/${file}/${subfile}`).default; if (command.setup) { @@ -77,7 +77,7 @@ client.on("interactionCreate", async (interaction) => { if (!interaction.member?.roles.includes(env.ADMIN_ROLE_ID ?? "")) return; const message = await client.getMessage(interaction.message.channel.id, interaction.message.id); - let posibleName: string[] = []; + const posibleName: string[] = []; message.referencedMessage?.components?.forEach((x) => { x.components.map((y) => { if ("custom_id" in y) { @@ -86,7 +86,7 @@ client.on("interactionCreate", async (interaction) => { }); }); - let name = posibleName[0] || interaction?.message?.interaction?.name.split(" ").join("-").toLowerCase() || interaction.data.custom_id.split(" ").join("-").toLowerCase(); + const name = posibleName[0] || interaction?.message?.interaction?.name.split(" ").join("-").toLowerCase() || interaction.data.custom_id.split(" ").join("-").toLowerCase(); if (client.commands.has(name)) return client.commands.get(name).onInteraction(client, interaction); } diff --git a/anify-manager/src/discord/commands/anify/pull.ts b/anify-manager/src/discord/commands/anify/pull.ts index 70950f1..f531933 100644 --- a/anify-manager/src/discord/commands/anify/pull.ts +++ b/anify-manager/src/discord/commands/anify/pull.ts @@ -18,7 +18,7 @@ export default { ], }, on: async (client: Client, interaction: CommandInteraction) => { - let value = (interaction?.data?.options?.[0] as any)?.options?.[0]?.value as string; + const value = (interaction?.data?.options?.[0] as any)?.options?.[0]?.value as string; if (!interaction.acknowledged) await interaction.acknowledge(1); diff --git a/anify-manager/src/discord/commands/anify/run.ts b/anify-manager/src/discord/commands/anify/run.ts index e3f5f7f..c9a4bf3 100644 --- a/anify-manager/src/discord/commands/anify/run.ts +++ b/anify-manager/src/discord/commands/anify/run.ts @@ -57,8 +57,7 @@ export default { ]); }, on: async (client: Client, interaction: CommandInteraction) => { - // @ts-ignore - let value = interaction?.data?.options?.[0]?.options?.[0]?.value as string; + const value = (interaction?.data?.options?.[0] as any)?.options?.[0]?.value as string; const embed = await logic(value); interaction.createMessage(embed); diff --git a/anify-manager/src/discord/commands/anify/stop.ts b/anify-manager/src/discord/commands/anify/stop.ts new file mode 100644 index 0000000..7b2b4b0 --- /dev/null +++ b/anify-manager/src/discord/commands/anify/stop.ts @@ -0,0 +1,59 @@ +import * as response from "../../responses/anify"; + +import { kill } from "../../../utils/pm2"; +import view from "../../../utils/fs/view"; +import { runCommands } from "../../../config"; +import { AutocompleteInteraction, Client, CommandInteraction, Constants, TextableChannel } from "eris"; + +export default { + name: "stop", + schema: { + name: "stop", + description: "stop a running processes of PM2.", + type: Constants.ApplicationCommandTypes.CHAT_INPUT, + options: [ + { + name: "version", + description: "Select a version to stop.", + type: Constants.ApplicationCommandOptionTypes.STRING, + autocomplete: true, + }, + ], + }, + autocomplete: (client: Client, interaction: AutocompleteInteraction) => { + // get the current text the user has sent + const firstOptions = interaction.data.options[0]; + let secondOptions: any = {}; + let text: string; + + if ("options" in firstOptions) { + secondOptions = firstOptions?.options?.at(0); + } + if ("value" in secondOptions) { + text = secondOptions?.value as string; + } + + const list = view().filter((x) => x.name.includes(text)); + interaction.result([ + ...list.map((x) => ({ + name: x.name, + value: x.name, + })), + { + name: "latest", + value: "latest", + }, + ]); + }, + on: async (client: Client, interaction: CommandInteraction) => { + let name: string | undefined = (interaction?.data?.options?.[0] as any)?.options?.[0]?.value as string; + const keys = Object.keys(runCommands); + const list = view(); + + if (name == "latest") name = list[0].name; + + const data = await kill(keys.map((x) => list.find((x) => x.name == name)?.name + `-${x}` || name + `-${x}`)); + + interaction.createMessage(response.stopRepo.message(data)); + }, +}; diff --git a/anify-manager/src/discord/commands/anify/update.ts b/anify-manager/src/discord/commands/anify/update.ts new file mode 100644 index 0000000..2abd082 --- /dev/null +++ b/anify-manager/src/discord/commands/anify/update.ts @@ -0,0 +1,74 @@ +import * as response from "../../responses/anify"; +import { update } from "../../../utils/pm2"; +import view from "../../../utils/fs/view"; + +import running from "./running"; +import { AutocompleteInteraction, Client, CommandInteraction, ComponentInteraction, Constants, TextableChannel } from "eris"; + +const logic = async (value?: string) => { + const list = view(); + console.log(list[0]); + if (value == "latest" || !value) value = list[0].name; + console.log(value); + + const data = await update({ + label: value, + }); + + if (data.error) return response.update.error.message(`${data.error}`); + return response.update.message(data); +}; + +export default { + name: "update", + schema: { + name: "update", + description: "Updates the repos of a label.", + type: Constants.ApplicationCommandTypes.CHAT_INPUT, + options: [ + { + name: "select", + description: "Select a label to update contents of.", + type: Constants.ApplicationCommandOptionTypes.STRING, + autocomplete: true, + required: true, + }, + ], + }, + autocomplete: (client: Client, interaction: AutocompleteInteraction) => { + // get the current text the user has sent + const firstOptions = interaction.data.options[0]; + let secondOptions: any = {}; + let text: string; + + if ("options" in firstOptions) { + secondOptions = firstOptions?.options?.at(0); + } + if ("value" in secondOptions) { + text = secondOptions?.value as string; + } + + const list = view().filter((x) => x.name.includes(text)); + interaction.result([ + ...list.map((x) => ({ + name: x.name, + value: x.name, + })), + ]); + }, + on: async (client: Client, interaction: CommandInteraction) => { + const value = (interaction?.data?.options?.[0] as any)?.options?.[0]?.value as string; + + if (!interaction.acknowledged) await interaction.acknowledge(1); + const embed = await logic(value); + interaction.editOriginalMessage(embed); + }, + onInteraction: async (client: Client, interaction: ComponentInteraction) => { + // This is a button to make view the running scripts + console.log(interaction.data); + if (interaction.data.component_type === 2) { + interaction.createMessage(await running.logic()); + } + }, + logic, +}; diff --git a/anify-manager/src/utils/pm2/build.ts b/anify-manager/src/utils/pm2/build.ts index 98322f2..5baf65d 100644 --- a/anify-manager/src/utils/pm2/build.ts +++ b/anify-manager/src/utils/pm2/build.ts @@ -6,7 +6,7 @@ import { copyFileSync, createWriteStream, existsSync, mkdirSync } from "fs"; const execPromise = promisify(exec); export default async function build(label: string, name: string[], count: number) { - let data: { error?: any[]; data: any[] } = { + const data: { error?: any[]; data: any[] } = { error: undefined, data: [], }; diff --git a/anify-manager/src/utils/pm2/index.ts b/anify-manager/src/utils/pm2/index.ts index a5f786c..181b424 100644 --- a/anify-manager/src/utils/pm2/index.ts +++ b/anify-manager/src/utils/pm2/index.ts @@ -4,6 +4,4 @@ import run from "./run"; import build from "./build"; import update from "./update"; -export const runningProcesses: Map = new Map(); - export { list, kill, run, build, update }; diff --git a/anify-manager/src/utils/pm2/init.ts b/anify-manager/src/utils/pm2/init.ts new file mode 100644 index 0000000..f0bad1d --- /dev/null +++ b/anify-manager/src/utils/pm2/init.ts @@ -0,0 +1,17 @@ +import pm2 from "pm2"; + +let pm2Initilized: boolean = false; + +export default (): Promise => { + if (pm2Initilized) return Promise.resolve(); + return new Promise((resolve, reject) => { + pm2.connect((err) => { + if (err) { + console.error(err); + reject(err); + } + pm2Initilized = true; + resolve(); + }); + }); +}; diff --git a/anify-manager/src/utils/pm2/kill.ts b/anify-manager/src/utils/pm2/kill.ts index dcf7e17..4790d52 100644 --- a/anify-manager/src/utils/pm2/kill.ts +++ b/anify-manager/src/utils/pm2/kill.ts @@ -1,4 +1,5 @@ -import { runningProcesses } from "."; +import pm2 from "pm2"; +import init from "./init"; interface IResponse { error?: string; @@ -6,6 +7,8 @@ interface IResponse { } const kill = async (names: string | number | (string | number)[]): Promise => { + await init(); + if (!Array.isArray(names)) { names = [names]; } @@ -13,8 +16,13 @@ const kill = async (names: string | number | (string | number)[]): Promise { return new Promise((resolve, reject) => { - runningProcesses.get(String(name))?.kill(); - resolve({ data: `killed ${name}` }); + pm2.delete(name, (err, results) => { + if (err) { + resolve({ error: err.message as string, data: name as string }); + } else { + resolve({ data: "success" }); + } + }); }); }) ); diff --git a/anify-manager/src/utils/pm2/list.ts b/anify-manager/src/utils/pm2/list.ts index 629f6ae..c70654c 100644 --- a/anify-manager/src/utils/pm2/list.ts +++ b/anify-manager/src/utils/pm2/list.ts @@ -1,4 +1,5 @@ -import { runningProcesses } from "."; +import pm2 from "pm2"; +import init from "./init"; export interface IResponse extends Object { error?: string; @@ -9,15 +10,17 @@ export interface IResponse extends Object { } const list = async (): Promise => { - return new Promise((resolve, reject) => { - const data = Array.from(runningProcesses.keys()).map((x) => { - if (!x) return; - return { name: x, pid: runningProcesses.get(x)?.pid } - }).filter((x) => x) as any; + await init(); - // Also get all processes that use node + return new Promise((resolve, reject) => { + pm2.list((err, list) => { + if (err) { + console.error(err); + return resolve({ error: err.message, data: [] }); + } - resolve({ data }); + resolve({ data: list.map((x) => ({ name: x.name, pid: x.pid })) }); + }); }); }; diff --git a/anify-manager/src/utils/pm2/run.ts b/anify-manager/src/utils/pm2/run.ts index f6690ba..1d0ff81 100644 --- a/anify-manager/src/utils/pm2/run.ts +++ b/anify-manager/src/utils/pm2/run.ts @@ -1,8 +1,8 @@ import { runCommands } from "../../config"; import { promisify } from "util"; import fs from "fs"; -import { runningProcesses } from "."; -import { spawn } from "node:child_process"; +import pm2 from "pm2"; +import init from "./init"; interface BuildDetail { error?: string; @@ -10,6 +10,8 @@ interface BuildDetail { } const run = async (folderName: string): Promise => { + await init(); + const builds = (await promisify(fs.readdir)("./builds")) as any[]; const buildStats = await Promise.all(builds.map((build) => promisify(fs.stat)(`./builds/${build}`))); const latestBuild = folderName ?? builds[buildStats.filter((stat: any) => stat.isDirectory()).length - 1]; @@ -22,28 +24,24 @@ const run = async (folderName: string): Promise => { const value = runCommands[key]; await new Promise((resolve, reject) => { - // Startup process - const childProcess = spawn("pnpm", value.split(" "), { - cwd: `./builds/${latestBuild}/${key}`, - detached: true - }); - - childProcess.unref(); - - runningProcesses.set(latestBuild + "-" + key, childProcess); - - childProcess.stdout.on("data", (data) => { - buildDetails.push({ data: data.toString() }); - }); - - childProcess.on("error", (err) => { - console.error(err); - buildDetails.push({ error: err.message }); - }); - - buildDetails.push({ data: `running ${latestBuild}, ${key}` }); - - resolve() + pm2.start( + { + script: `pnpm`, + args: value.split(" "), + cwd: `./builds/${latestBuild}/${key}`, + name: latestBuild + "-" + key, + }, + (err, apps) => { + if (err) { + console.log(err); + buildDetails.push({ error: err.message }); + } else { + buildDetails.push({ data: `running ${latestBuild}, ${key}` }); + } + + resolve(); + } + ); }); } diff --git a/anify-manager/src/utils/pm2/update.ts b/anify-manager/src/utils/pm2/update.ts index 017ffd7..75d3d80 100644 --- a/anify-manager/src/utils/pm2/update.ts +++ b/anify-manager/src/utils/pm2/update.ts @@ -26,7 +26,7 @@ const customPromisify = ( }; export default async function update({ label = "auto", name = Object.keys(buildCommands) }: { label?: string; name?: string[] }) { - let data: { error?: any[]; data: any[] } = { + const data: { error?: any[]; data: any[] } = { error: undefined, data: [], }; @@ -133,8 +133,7 @@ export default async function update({ label = "auto", name = Object.keys(buildC // we assume a victroy so now run fs.utimesSync( path, atime, mtime ) on the buildFolder const newTime = new Date(); fs.utimesSync(buildPath, newTime, newTime); - } catch (error) { - // @ts-ignore + } catch (error: any) { const errorMessage = error.message || error; console.error(`buildRepo error: ${errorMessage}`); data.error = [{ message: errorMessage }]; diff --git a/anify-manager/tsconfig.json b/anify-manager/tsconfig.json index 388a057..8b78649 100644 --- a/anify-manager/tsconfig.json +++ b/anify-manager/tsconfig.json @@ -18,5 +18,9 @@ "types": [ "bun-types" // add Bun global ] - } + }, + "exclude": [ + "node_modules", + "builds" + ] } From 7832aa4f9c355fdc54a847ba499cfb60c775c84d Mon Sep 17 00:00:00 2001 From: Eltik Date: Fri, 15 Sep 2023 11:40:21 -0400 Subject: [PATCH 37/77] Add crawling file --- anify-backend/db.sqlite | Bin 5808128 -> 5808128 bytes anify-backend/src/lib/impl/crawl.ts | 85 +++++++++++ .../src/mappings/impl/base/anilist.ts | 139 ++++++++++++++++++ anify-backend/src/mappings/impl/base/index.ts | 2 +- .../src/mappings/impl/base/mangadex.ts | 17 +++ 5 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 anify-backend/src/lib/impl/crawl.ts diff --git a/anify-backend/db.sqlite b/anify-backend/db.sqlite index 9661d2b6be594912253a56fb7a15e12a16fb1572..d7a32a23df891342274eebbe35d4ff00cfc9f2cc 100644 GIT binary patch delta 86314 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 aPZvMk{PghC%TFIayT7~dFZ-YTtN#nCZ6)>q delta 2057 zcmZ|Qe@q+q6##JG`Ny4&@6IL|+aVY`V4Dz1&xJrkaQrpkQqlpYEltyf)U56PSeIZX zHAy#Vm_#F6vMgq-dFt9Ju(EVjr4Gi%Q#w^KBkh_=RiGmi+Pc(bTbfi&XT~(GYc%cM zvF(p_`{N_q@B96}@AuxlJ7;pMe1>Gpq^kyl`J};MI7)7hRX1^0XHruY;@$EM3K*qv zyFWcU0T$$-aNOjD^r_-WNUg+7@XD__28FvGI=}Jr^bx)dFFwcOrvIH4DeKE7?F2IP zu8T29moNoSb+e~9{9-lxjsU3^Ru7L3vq_kEN$7+^C3E6|3_D`h7AY|Dq`74ycyc#8 zOp83)qS`^W42}my4;K9FffB)k@=y@!Akg#(=c$;_}Nb_#AG2jt-$nDK%e>uhtvs|g6!?qoCMjq_I)_~vFC`sY86#yXi>)em%X)m;P((e zT*WXQ2xaBDzTF$aKS0D?wF?!#ZB2sdT*M9OOQi$aZF^W>^hcOnsp-avTzN`4TUQ!} zE3bOO+WD`;nmN#p6OUDrJKsQchyrK#o2U-o@L2TB zH(|2fHGmb)#CtLn)?NCo`~c>sggzYfhsUTYU+|R9W$Snc&wmKL->acsU}5S7Hlr8o z7R1lG!gyw;d`QM5R&A8!BOG|s6a7@56)eaOC35sGY%A4w`V*|ZAN@RL(&3B(xki_k z(rARS3V%QTDDCT|_FAs0g3RNkHKT>Pxx$@Bl{3N8x0NWK$@qq-P0O}-YirCfblFvp zXV!y5cCGt-nEip!Y}AGWA$NFV4*}x4wjaRhXTVBLf13+_>^PDU$CzT?@1gY}^?J7iyU#qr_`F1McF27yLX_`e^ie_txnr7r3z ziXc+%rl&^jpr@u_EYk{Lw8O}`>Q0O~nr0R4w}k3gnEFLM7OLf}61~?rsox+$?>X+r zvl+)N3okxGe@(OI6a8og~OT nq=Vc`I>{b#ANdUFBHg5iBuOv1pFBVwBz@!|?0;+T3vd4uDuun| diff --git a/anify-backend/src/lib/impl/crawl.ts b/anify-backend/src/lib/impl/crawl.ts new file mode 100644 index 0000000..5d16e3c --- /dev/null +++ b/anify-backend/src/lib/impl/crawl.ts @@ -0,0 +1,85 @@ +import { db, init } from "../../database"; +import { BASE_PROVIDERS } from "../../mappings"; +import { Format, Type } from "../../types/enums"; +import { Anime, Manga } from "../../types/types"; + +import colors from "colors"; +import { loadMapping } from "./mappings"; +import queues from "../../worker"; +import { fetchCorsProxies } from "../../proxies/impl/fetchProxies"; +import emitter, { Events } from ".."; +import { get } from "../../database/impl/modify/get"; +import { wait } from "../../helper"; + +export const crawl = async (format: Format): Promise => { + await before(); + + const provider = await BASE_PROVIDERS.map((provider) => { + if (provider.formats?.includes(format)) { + return provider; + } else { + return null; + } + }).filter((x) => x !== null)[0]; + + if (!provider) return; + + const ids = (await provider.fetchIds(format)) ?? []; + + const idsToRemove: string[] = []; + const database = (await db.query(`SELECT id FROM ${format === Format.TV || format === Format.TV_SHORT || format === Format.MOVIE || format === Format.MUSIC || format === Format.OVA || format === Format.ONA || format === Format.SPECIAL ? "anime" : "manga"} WHERE format = $format`).all({ $format: format })) as Anime[] | Manga[]; + + database.forEach((media) => { + idsToRemove.push(media.id); + }); + + const numbersSet: Set = new Set(idsToRemove); + const cleanedIds: string[] = ids.filter((str) => !numbersSet.has(str)); + + console.log(colors.gray("Found " + ids.length + " IDs, " + cleanedIds.length + " of which are not in the database.")); + + const chunkSize = 10; + + const data: Anime[] | Manga[] = []; + + for (let i = 0; i < cleanedIds.length; i += chunkSize) { + const now = Date.now(); + const chunk = cleanedIds.slice(i, i + chunkSize); + const mappings: Anime[] | Manga[] = []; + + await Promise.all( + chunk.map((id) => { + return loadMapping({ id, formats: [format], type: format === Format.TV || format === Format.TV_SHORT || format === Format.MOVIE || format === Format.MUSIC || format === Format.OVA || format === Format.ONA || format === Format.SPECIAL ? Type.ANIME : Type.MANGA }).then((mapping) => { + if (mapping) { + mappings.push(...(mapping as any)); + } + }); + }), + ); + + data.push(...(mappings as any)); + + await wait(1000); + + console.log(colors.green(`Finished chunk ${i / chunkSize + 1}/${Math.ceil(cleanedIds.length / chunkSize)} in ${Date.now() - now}ms`)); + } + + console.log(colors.gray("Finished fetching data, now inserting into database.")); +}; + +async function before() { + await fetchCorsProxies(); + await init(); + + emitter.on(Events.COMPLETED_MAPPING_LOAD, async (data) => { + for (let i = 0; i < data.length; i++) { + if (await get(String(data[i].id))) { + continue; + } + queues.createEntry.add({ toInsert: data[i], type: data[i].type }); + } + }); + + queues.mappingQueue.start(); + queues.createEntry.start(); +} diff --git a/anify-backend/src/mappings/impl/base/anilist.ts b/anify-backend/src/mappings/impl/base/anilist.ts index fece257..34806ca 100644 --- a/anify-backend/src/mappings/impl/base/anilist.ts +++ b/anify-backend/src/mappings/impl/base/anilist.ts @@ -644,6 +644,145 @@ export default class AniListBase extends BaseProvider { }; } + override async fetchIds(format: Format): Promise { + const ids: string[] = []; + + if (format === Format.NOVEL || format === Format.MANGA || format === Format.ONE_SHOT) { + const mangaIds = await this.fetchMangaIds(format); + if (mangaIds) ids.push(...mangaIds); + } else { + const animeIds = await this.fetchAnimeIds(format); + if (animeIds) ids.push(...animeIds); + } + + return ids; + } + + private async fetchAnimeIds(format: Format): Promise { + const idList = await (await fetch("https://raw.githubusercontent.com/5H4D0WILA/IDFetch/main/ids.txt")).text(); + const list: string[] = idList.split("\n"); + + const chunkSize = 10; + + const ids: string[] = []; + + for (let i = 0; i < list.length; i += chunkSize) { + const now = Date.now(); + const chunk = list.slice(i, i + chunkSize); + const queries: string[] = []; + + await Promise.all( + chunk.map((id) => + queries.push(` + anime${id}:Page(page: 0, perPage: 10){ + media(id:${id}){ + id + type + format + } + } + `), + ), + ); + + const results: any[] = await this.batchRequest(queries, 5).catch((err) => { + return []; + }); + + if (results.includes(null)) { + // Too many requests. + continue; + } + + const batchResults: { id: number; type: Type; format: Format }[] = results + .reduce((accumulator, currentObject) => { + const mediaArrays = Object.values(currentObject).map((anime: any) => anime.media); + return accumulator.concat(...mediaArrays); + }, []) + .map((x: any) => { + if (!x) return null; + return x; + }) + .filter(Boolean); + + for (const media of batchResults) { + if (media.format === format) ids.push(String(media.id)); + } + + console.log(`Finished chunk ${i / chunkSize + 1}/${Math.ceil(list.length / chunkSize)} in ${Date.now() - now}ms`); + } + + return ids; + } + + private async fetchMangaIds(format: Format): Promise { + const req1 = await fetch("https://anilist.co/sitemap/manga-0.xml"); + const data1 = await req1.text(); + const req2 = await fetch("https://anilist.co/sitemap/manga-1.xml"); + const data2 = await req2.text(); + + const ids1 = data1.match(/manga\/([0-9]+)/g)?.map((id) => { + return id.replace("manga/", ""); + }); + + const ids2 = data2.match(/manga\/([0-9]+)/g)?.map((id) => { + return id.replace("manga/", ""); + }); + const list = ids1?.concat(ids2 as string[]) ?? []; + + const chunkSize = 10; + + const ids: string[] = []; + + for (let i = 0; i < list.length; i += chunkSize) { + const now = Date.now(); + const chunk = list.slice(i, i + chunkSize); + const queries: string[] = []; + + await Promise.all( + chunk.map((id) => + queries.push(` + anime${id}:Page(page: 0, perPage: 10){ + media(id:${id}){ + id + type + format + } + } + `), + ), + ); + + const results: any[] = await this.batchRequest(queries, 5).catch((err) => { + return []; + }); + + if (results.includes(null)) { + // Too many requests. + continue; + } + + const batchResults: { id: number; type: Type; format: Format }[] = results + .reduce((accumulator, currentObject) => { + const mediaArrays = Object.values(currentObject).map((anime: any) => anime.media); + return accumulator.concat(...mediaArrays); + }, []) + .map((x: any) => { + if (!x) return null; + return x; + }) + .filter(Boolean); + + for (const media of batchResults) { + if (media.format === format) ids.push(String(media.id)); + } + + console.log(`Finished chunk ${i / chunkSize + 1}/${Math.ceil(list.length / chunkSize)} in ${Date.now() - now}ms`); + } + + return ids; + } + private anilistMediaGenerator(data: any): AnimeInfo | MangaInfo { return { id: String(data.id), diff --git a/anify-backend/src/mappings/impl/base/index.ts b/anify-backend/src/mappings/impl/base/index.ts index a6211fb..6db9dab 100644 --- a/anify-backend/src/mappings/impl/base/index.ts +++ b/anify-backend/src/mappings/impl/base/index.ts @@ -31,7 +31,7 @@ export default abstract class BaseProvider { return undefined; } - async fetchIds(): Promise { + async fetchIds(format: Format): Promise { return undefined; } diff --git a/anify-backend/src/mappings/impl/base/mangadex.ts b/anify-backend/src/mappings/impl/base/mangadex.ts index a31f457..cd7b633 100644 --- a/anify-backend/src/mappings/impl/base/mangadex.ts +++ b/anify-backend/src/mappings/impl/base/mangadex.ts @@ -359,6 +359,23 @@ export default class ManagDexBase extends BaseProvider { }; } + override async fetchIds(): Promise { + const data = await (await this.request("https://raw.githubusercontent.com/ArdaxHz/mangadex-id-map/main/json/manga_map.json")).json(); + /* + { + "1": "c0ee660b-f9f2-45c3-8068-5123ff53f84a", + "2": "7dbeaa0e-420a-4dc0-b2d3-eb174de266da", + ... + } + */ + const ids: string[] = []; + for (const id in data) { + ids.push(String(data[id])); + } + + return ids; + } + private returnFilledManga(manga: any) { const formatString: string = manga.type.toUpperCase(); const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; From ac0522e5f1b8407606f18d064452925af2eb9f93 Mon Sep 17 00:00:00 2001 From: Eltik Date: Fri, 15 Sep 2023 11:55:13 -0400 Subject: [PATCH 38/77] Shutdown page --- anify-frontend/src/pages/anime.tsx | 168 --- anify-frontend/src/pages/api/fetchEntry.tsx | 64 - anify-frontend/src/pages/api/mixdrop.tsx | 33 - anify-frontend/src/pages/api/og.tsx | 183 --- anify-frontend/src/pages/api/saveEntry.tsx | 64 - anify-frontend/src/pages/api/search.tsx | 124 -- anify-frontend/src/pages/api/user.tsx | 33 - anify-frontend/src/pages/index.tsx | 210 +-- anify-frontend/src/pages/info/[id].tsx | 1149 ----------------- anify-frontend/src/pages/login.tsx | 375 ------ anify-frontend/src/pages/logout.tsx | 51 - anify-frontend/src/pages/manga.tsx | 159 --- anify-frontend/src/pages/novels.tsx | 161 --- .../pages/read/[id]/[provider]/[readId].tsx | 656 ---------- .../[id]/[provider]/[watchId]/[subDub].tsx | 979 -------------- 15 files changed, 23 insertions(+), 4386 deletions(-) delete mode 100644 anify-frontend/src/pages/anime.tsx delete mode 100644 anify-frontend/src/pages/api/fetchEntry.tsx delete mode 100644 anify-frontend/src/pages/api/mixdrop.tsx delete mode 100644 anify-frontend/src/pages/api/og.tsx delete mode 100644 anify-frontend/src/pages/api/saveEntry.tsx delete mode 100644 anify-frontend/src/pages/api/search.tsx delete mode 100644 anify-frontend/src/pages/api/user.tsx delete mode 100644 anify-frontend/src/pages/info/[id].tsx delete mode 100644 anify-frontend/src/pages/login.tsx delete mode 100644 anify-frontend/src/pages/logout.tsx delete mode 100644 anify-frontend/src/pages/manga.tsx delete mode 100644 anify-frontend/src/pages/novels.tsx delete mode 100644 anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx delete mode 100644 anify-frontend/src/pages/watch/[id]/[provider]/[watchId]/[subDub].tsx diff --git a/anify-frontend/src/pages/anime.tsx b/anify-frontend/src/pages/anime.tsx deleted file mode 100644 index a45b7a0..0000000 --- a/anify-frontend/src/pages/anime.tsx +++ /dev/null @@ -1,168 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import axios from "axios"; - -import { type GetServerSideProps, type NextPage } from "next"; -import Sidebar from "~/components/sidebar"; - -import { env } from "~/env.mjs"; -import Footer from "~/components/footer"; -import { type Seasonal, type Anime, type WatchTime } from "~/types"; -import Slideshow from "~/components/slideshow"; -import Navbar from "~/components/navbar"; -import LargeSlideshow from "~/components/largeSlideshow"; -import Head from "next/head"; -import { useStore } from "zustand"; -import { Swiper, SwiperSlide } from "swiper/react"; -import Link from "next/link"; -import { useWatchTime } from "~/store/store"; -import { useEffect, useState } from "react"; - -const Anime: NextPage = ({ seasonal, recent }) => { - const [watchTime, setWatchTime] = useState([]); - - const storedWatchTime = useStore(useWatchTime, ((state: any) => state.currentTime as WatchTime[])); - - useEffect(() => { - const uniqueWatchTimeMap = new Map(); - - for (const time of storedWatchTime) { - uniqueWatchTimeMap.set(time.mediaId, time); - } - - const newWatchTime = Array.from(uniqueWatchTimeMap.values()); - setWatchTime(newWatchTime); - }, [storedWatchTime]); - - return ( - <> - - {"Anime"} - - - - - - - - - - - - - - - - - - -
-
-
- -
- {watchTime?.length > 0 ? ( -
-

Continue Watching

- - {watchTime.map((media, index: number) => { - return ( - -
-
-
- - {(media.title?.english - -
-
- - - - - - - - - - -
-
- {/* Progress Bar */} - {media.duration && media.currentTime ? ( -
-
-
- ) : null} -
-
-
    -
  • {media.title?.english ?? media.title?.romaji ?? media.title?.native ?? "N/A"}
  • -
  • - {media.episodeNumber ? Episode {media.episodeNumber} : null} -
  • -
-
-
-
-
- ) - })} -
-
- ) : null} -
-

Recent Episodes

- -
-
-

Seasonal

- -
-
-

Popular

- -
-
-

Highest Rated

- -
-
-
-
- - ); -}; - -export const getServerSideProps: GetServerSideProps = async () => { - const seasonal = (await axios.get(String(env.BACKEND_URL) + "/seasonal?type=anime&fields=[id,description,bannerImage,coverImage,title,genres,format,averageRating,episodes,chapters,year]&apikey=" + String(env.API_KEY))).data as Seasonal; - const recent = (await axios.get(String(env.BACKEND_URL) + "/recent?type=anime&apikey=" + String(env.API_KEY))).data as Anime[]; - - return { - props: { - seasonal, - recent, - }, - }; -}; - -export default Anime; - -interface Props { - seasonal?: Seasonal; - recent?: Anime[]; -} diff --git a/anify-frontend/src/pages/api/fetchEntry.tsx b/anify-frontend/src/pages/api/fetchEntry.tsx deleted file mode 100644 index 2d49adf..0000000 --- a/anify-frontend/src/pages/api/fetchEntry.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import { type ServerResponse } from "http"; -import { env } from "~/env.mjs"; -import { type UserData } from "~/types"; - -export default async function handler(request: Request, response: ServerResponse) { - if (!request.body.provider) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing provider." })); - response.end(); - return; - } - if (!request.body.userId) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing user ID." })); - response.end(); - return; - } - if (!request.body.accessToken) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing access token." })); - response.end(); - return; - } - if (!request.body.mediaId) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing media ID." })); - response.end(); - return; - } - - try { - const data = await (await fetch(`${env.AUTH_URL}/${request.body.provider}/entry`, { - method: "POST", - body: JSON.stringify({ - userId: request.body.userId, - accessToken: request.body.accessToken, - mediaId: request.body.mediaId - }), - headers: { - "Content-Type": "application/json" - } - })).json(); - - response.writeHead(200, { "Content-Type": "application/json" }); - response.write(JSON.stringify(data)); - response.end(); - return; - } catch (e) { - response.writeHead(500, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Internal server error." })); - response.end(); - return; - } -} - -interface Request { - body: { - provider: string; - userId: string; - accessToken: string; - mediaId: string; - } -} \ No newline at end of file diff --git a/anify-frontend/src/pages/api/mixdrop.tsx b/anify-frontend/src/pages/api/mixdrop.tsx deleted file mode 100644 index b8c4816..0000000 --- a/anify-frontend/src/pages/api/mixdrop.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { type ServerResponse } from "http"; -import { env } from "~/env.mjs"; -import { type MixdropResponse } from "~/types"; - -export default async function handler(request: Request, response: ServerResponse) { - if (!request.body.id) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing mixdrop ID." })); - response.end(); - return; - } - - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const data: MixdropResponse = await (await fetch(`${env.BACKEND_URL}/pages-download?apikey=${env.API_KEY}`, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({ - id: request.body.id - }) - })).json(); - - response.writeHead(200, { "Content-Type": "application/json" }); - response.write(JSON.stringify(data)); - response.end(); -} - -interface Request { - body: { - id: string; - } -} \ No newline at end of file diff --git a/anify-frontend/src/pages/api/og.tsx b/anify-frontend/src/pages/api/og.tsx deleted file mode 100644 index b7f2b45..0000000 --- a/anify-frontend/src/pages/api/og.tsx +++ /dev/null @@ -1,183 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import { ImageResponse } from "@vercel/og"; -import sanitizer from "sanitize-html"; -import { env } from "~/env.mjs"; -import { type Anime, type Manga } from "~/types"; - -export const textSanitizer = (textWithHTML:string) => { - return sanitizer(textWithHTML, { - allowedTags: [], - }); -}; - -export const config = { - runtime: "edge", -}; - -const getDetails = async (id:string): Promise => { - const data: Anime | Manga = await (await fetch(`${env.BACKEND_URL}/info/${id}?apikey=${env.API_KEY}`)).json(); - return data; -}; - -function capitalize(s:string) { - s = s.toLowerCase(); - return s && String(s[0]?.toUpperCase()) + s.slice(1); -} - -const RegularFont = fetch( - new URL("../../../fonts/Inter-Bold.ttf", import.meta.url) -).then((res) => res.arrayBuffer()); - -export default async function handler(req: { url: string; }) { - try { - const RegularFontData = await RegularFont; - const { searchParams } = new URL(decodeURIComponent(req.url)); - - const id = searchParams.has("id") ? searchParams.get("id") : null; - - if (!id) { - return new Response(`Missing id`, { status: 400, }); - } - - const data = await getDetails(id); - - if (!data) return new Response(`Missing data`, { status: 400 }); - - const { - bannerImage, - genres, - coverImage, - averageRating, - year, - status - } = data; - - const title = (data.title?.english || data.title?.romaji || data.title?.native || "Unknown").replace(/[\u{0080}-\u{10FFFF}]/gu, ""); - - const color = "rgb(76, 184, 117)"; - - const titleLength = 80; - - return new ImageResponse( - ( -
-
-
-

- {capitalize(status ?? "")} - {year} -

-

- {title.length > titleLength ? title.substring(0, 80) + "..." : title} -

-

- {data.status && data.format ? `${capitalize(data.status as string)} · ${capitalize(data.format as string)}` : capitalize(data.format as string)} -

-
- - - - {averageRating ? String(Math.round(averageRating * 10)) + "%" : "?"} -
-
- {genres?.splice(0, 4)?.map((genre: any) => ( -
- {genre} -
- ))} -
-
- -
- ), - { - width: 1200, - height: 628, - fonts: [ - { - name: "Inter-Bold", - data: RegularFontData, - style: "normal", - }, - ], - } - ); - } catch (e) { - console.error(e); - return new Response(`Failed to generate the image`, { - status: 500, - }); - } -} \ No newline at end of file diff --git a/anify-frontend/src/pages/api/saveEntry.tsx b/anify-frontend/src/pages/api/saveEntry.tsx deleted file mode 100644 index 60e8fdc..0000000 --- a/anify-frontend/src/pages/api/saveEntry.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import { type ServerResponse } from "http"; -import { env } from "~/env.mjs"; -import { type Entry } from "~/types"; - -export default async function handler(request: Request, response: ServerResponse) { - if (!request.body.provider) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing provider." })); - response.end(); - return; - } - if (!request.body.userId) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing user ID." })); - response.end(); - return; - } - if (!request.body.accessToken) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing access token." })); - response.end(); - return; - } - if (!request.body.entry) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing entry." })); - response.end(); - return; - } - - try { - const data = await (await fetch(`${env.AUTH_URL}/${request.body.provider}/update-entry`, { - method: "POST", - body: JSON.stringify({ - userId: request.body.userId, - accessToken: request.body.accessToken, - entry: request.body.entry - }), - headers: { - "Content-Type": "application/json" - } - })).json(); - - response.writeHead(200, { "Content-Type": "application/json" }); - response.write(JSON.stringify(data)); - response.end(); - return; - } catch (e) { - response.writeHead(500, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Internal server error." })); - response.end(); - return; - } -} - -interface Request { - body: { - provider: string; - userId: string; - accessToken: string; - entry: Entry; - } -} \ No newline at end of file diff --git a/anify-frontend/src/pages/api/search.tsx b/anify-frontend/src/pages/api/search.tsx deleted file mode 100644 index c405dfe..0000000 --- a/anify-frontend/src/pages/api/search.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import { type ServerResponse } from "http"; -import { env } from "~/env.mjs"; -import { type Anime, type Manga, type Format, type MediaStatus } from "~/types"; - -export default async function handler(request: Request, response: ServerResponse) { - if (!request.body.query) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing query." })); - response.end(); - return; - } - - if (!request.body.type) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing type (anime/manga)." })); - response.end(); - return; - } - - const perPage: number = request.body.perPage ?? 10; - const page: number = request.body.page ?? 0; - - const genres: string[] = request.body.genres ?? []; - const genresExcluded: string[] = request.body.genresExcluded ?? []; - const tags: string[] = request.body.tags ?? []; - const tagsExcluded: string[] = request.body.tagsExcluded ?? []; - - const formats: string[] = request.body.formats ?? []; - - const data = await (await fetch(`${env.BACKEND_URL}/search-advanced?apikey=${env.API_KEY}`, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({ - type: request.body.type === "manga" ? formats.includes("NOVEL") ? "novel" : "manga" : "anime", - query: request.body.query, - format: formats, - page, - perPage, - genres, - genresExcluded, - tags, - tagsExcluded, - year: 0, - }) - })).json() as Anime[] | Manga[]; - - const newData = { - hits: data, - query: request.body.query, - processingTimeMs: 0, - limit: perPage, - offset: page * perPage, - estimatedTotalHits: data.length, - } - - response.writeHead(200, { "Content-Type": "application/json" }); - response.write(JSON.stringify(newData)); - response.end(); -} - -interface Request { - body: { - query: string; - type: string; - perPage?: number; - page?: number; - genres?: string[]; - genresExcluded?: string[]; - tags?: string[]; - tagsExcluded?: string[]; - formats?: string[]; - } -} - -interface Title { - native: string; - romaji: string; - english: string; -} - -export interface SearchItem { - title: Title; - description: string; - synonyms: string[]; - id: string; - coverImage: string; - bannerImage: string; - year: number; - genres: string[]; - tags: string[]; - status: MediaStatus; - season: string; - format: Format; - rating: { - mal: number; - kitsu: number; - anilist: number; - simkl?: number; - }; - popularity: { - mal: number; - kitsu: number; - anilist: number; - simkl?: number; - }; - color: string; - mappings: { - id: string; - providerId: string; - similarity: number; - providerType: string; - }[]; -} - -export interface SearchResult { - hits: SearchItem[]; - query: string; - processingTimeMs: number; - limit: number; - offset: number; - estimatedTotalHits: number; -} \ No newline at end of file diff --git a/anify-frontend/src/pages/api/user.tsx b/anify-frontend/src/pages/api/user.tsx deleted file mode 100644 index 0b0cfc5..0000000 --- a/anify-frontend/src/pages/api/user.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { type ServerResponse } from "http"; -import { env } from "~/env.mjs"; -import { type UserData } from "~/types"; - -export default async function handler(request: Request, response: ServerResponse) { - if (!request.body.id) { - response.writeHead(400, { "Content-Type": "application/json" }); - response.write(JSON.stringify({ message: "Missing ID." })); - response.end(); - return; - } - - const data = await (await fetch(`${env.AUTH_URL}/user`, { - method: "POST", - body: JSON.stringify({ - id: request.body.id - }), - headers: { - "Content-Type": "application/json" - } - })).json() as UserData; - - response.writeHead(200, { "Content-Type": "application/json" }); - response.write(JSON.stringify(data)); - response.end(); - return; -} - -interface Request { - body: { - id: string; - } -} \ No newline at end of file diff --git a/anify-frontend/src/pages/index.tsx b/anify-frontend/src/pages/index.tsx index a8d8837..a9a8adb 100644 --- a/anify-frontend/src/pages/index.tsx +++ b/anify-frontend/src/pages/index.tsx @@ -1,27 +1,11 @@ -import axios from "axios"; -import { useSpring, animated } from "react-spring"; import Link from "next/link"; -import { type GetServerSideProps, type NextPage } from "next"; -import Sidebar from "~/components/sidebar"; +import { type NextPage } from "next"; -import { env } from "~/env.mjs"; import Footer from "~/components/footer"; -import { type Stats } from "~/types"; -import Navbar from "~/components/navbar"; import Head from "next/head"; -const Home: NextPage = ({ stats }) => { - const AnimatedNumber = ({ value }: { value: number }) => { - const animatedProps = useSpring({ from: { value: 0 }, to: { value } }); - - return ( - - {animatedProps.value.interpolate((val) => Math.floor(val))} - - ); - }; - +const Home: NextPage = () => { return ( <> @@ -42,165 +26,31 @@ const Home: NextPage = ({ stats }) => { - -
-
-
-

Anify

-

Watch anime in HD quality, read manga seamlessly with easy-to-use features, catch up with your favorite light novels, and more all in one place.

-
-
-
-
- Get Started -
-
-
-
- -
-

Advanced

-

- Anify has gone through many redesigns to match the best websites out there. -

-
-
-
- -
-

Customizable

-

- Change Anify's functions to personalize your experience. -

-
-
-
- -
-

Seamless

-

- Each feature is vetted to make sure each user has the best experience possible. -

-
-
-
-
-
-

Modern

-

Revolutionizing Anime Websites

-

- Using the latest technologies, Anify is able to provide a seamless experience for all users. +

+

Anify

+

Hey everyone! I am terribly sorry, but the public domain for Anify will be shutting down indefinitely. After a long road and a very successful journey, I have decided to shut down the frontend website indefinitely due to external circumstances. I don't feel comfortable giving people public access to pirated content, and the risk of a legal court case is too high for me to plausibly continue developing Anify. I have decided instead to make the source code open source with the aim to help others learn how to code. That may seem a bit strange considering that I am giving people the ability to develop their own anime websites, so in that case if the project becomes too successful I may make the code closed source again. However, Anify has taught me so much over the past few years that I want others to experience the same joy I had when learning how to code properly and create a clean code base. Anify has been a big part of my life and has helped me nurture my skills as a programmer enough that I hope others will learn from my mistakes and become a more successful programmer in their own way. With all that being said, you can access the GitHub repository via the Discord where you can ask for support and learn how to deevelop full-stack websites. Thank you everyone for the amazing experience and for supporting the website over the 3 years Anify has been up. I am sorry that I have to shut down this project, but all good things must come to an end at some point.

+

- Eltik

+
+

Credits/Additional Resources

+
    +
  • +

    + Eltik - Project owner, full-stack developer

    -
-
-
    -
  • -
    -
    -
    - - - - -
    -
    -
    -
    Experienced
    -

    Recoded and redesigned with the most popular anime, manga, and light novel websites in mind over many years.

    -
    -
    -
  • -
  • -
    -
    -
    - - - -
    -
    -
    -
    Continously Improved
    -

    Anify is built on the basis of tailoring each feature to what the community wants. Features are added based on what is popular and what is trending in the anime/manga/novel community.

    -
    -
    -
  • -
  • -
    -
    -
    - - - -
    -
    -
    -
    Reliable
    -

    With the use of multiple providers, if one anime or manga provider is down you can always keep up-to-date with your favorite shows and series.

    -
    -
    -
  • -
  • -
    -
    -
    - - - -
    -
    -
    -
    Active Community
    -

    Anify is powered by it's growing community implementing suggestions as they come so that the website will always be modern and unique compared to other popular websites.

    -
    -
    -
  • -
-
-
-
-
-
-
-

Large Library

-

Incredible Statistics

-

- Ever-increasing library of anime, manga, and light novels. + +

  • +

    + Consumet - Large inspiration for the project and provider support

    -
  • -
    -
    -
    -
    -
    -
    - -

    Anime

    -
    -
    - -

    Manga

    -
    -
    - -

    Novels

    -
    -
    - -

    Skip Times

    -
    -
    -
    -
    -
    + +
  • +

    + Chouten - Where Anify will be going next! +

    +
  • +
    @@ -210,18 +60,4 @@ const Home: NextPage = ({ stats }) => { ); }; -export const getServerSideProps: GetServerSideProps = async () => { - const data = (await axios.get(String(env.BACKEND_URL) + "/stats?apikey=" + String(env.API_KEY))).data as Stats; - - return { - props: { - stats: data, - }, - }; -}; - export default Home; - -interface Props { - stats: Stats; -} diff --git a/anify-frontend/src/pages/info/[id].tsx b/anify-frontend/src/pages/info/[id].tsx deleted file mode 100644 index 30fae34..0000000 --- a/anify-frontend/src/pages/info/[id].tsx +++ /dev/null @@ -1,1149 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @next/next/no-img-element */ -import axios from "axios"; - -import { type NextPage } from "next"; -import Head from "next/head"; -import Link from "next/link"; -import { useState } from "react"; -import Select from "react-select"; -import { useStore } from "zustand"; -import Chapter from "~/components/chapter"; -import Footer from "~/components/footer"; -import Navbar from "~/components/navbar"; - -import Sidebar from "~/components/sidebar"; - -import { env } from "~/env.mjs"; -import { capitalize, formatCompactNumber, isValidDate, parseFormat } from "~/helper"; -import { usePreferredList, useTokens, useUserData } from "~/store/store"; -import { type Anime, type Manga, type EpisodeData, type ChapterData, Type, Season, Format, type AnimeRelation, type MangaRelation, type UserData, type UserTokens, type Entry } from "~/types"; - -import NProgress from "nprogress"; - -const Info: NextPage = ({ media, relations, content }) => { - const [index, setIndex] = useState(0); // Provider index - - const [listData, setListData] = useState({} as Entry); - const [showList, setShowList] = useState(false); - const [status, setStatus] = useState(""); - - const [showDescription, setShowDescription] = useState(false); - - const [currentPage, setCurrentPage] = useState(1); - - const [currentSearch, setCurrentSearch] = useState(""); - const [subDub, setSubDub] = useState("sub"); - - const userData = useStore(useUserData, ((state: any) => state.userData as UserData)); - const userTokens = useStore(useTokens, ((state: any) => state.tokens as UserTokens[])); - const preferredList = useStore(usePreferredList, ((state: any) => state.preferredList as string)); - - const providerSelector = content.map((provider, index) => { - return { - value: index, - label: capitalize(provider.providerId) - } - }); - - function updateProviderIndex(data: { value: number, label: string } | null) { - const curIndex = index; - document.querySelector("#provider-" + String(curIndex))?.classList.add("hidden"); - - const newIndex = data?.value ?? 0; - setIndex(newIndex); - - document.querySelector("#provider-" + String(newIndex))?.classList.remove("hidden"); - } - - // Pagination - const chaptersPerPage = media.type === "ANIME" ? 12 : 24; - const startIndex = (currentPage - 1) * chaptersPerPage; - const endIndex = startIndex + chaptersPerPage; - - //const totalPages = Math.ceil(media.type === "ANIME" ? (content as EpisodeData[])[index]?.episodes?.length ?? 0 : ((content as ChapterData[])[index]?.chapters?.length ?? 0) / chaptersPerPage); - - const totalPages = Math.ceil(media.type === "ANIME" ? (content as EpisodeData[])[index]?.episodes.filter((episode) => { - if (subDub === "dub") { - return episode.hasDub; - } else { - return true; - } - }).length ?? 0 : ((content as ChapterData[])[index]?.chapters?.length ?? 0) / chaptersPerPage); - - const pagination = []; - - if (media.type != "ANIME") { - for (let index = 0; index < totalPages; index++) { - pagination.push( - - ) - } - } else { - const getPageNumbers = () => { - const pageNumbers = []; - for (let i = 1; i <= totalPages; i += chaptersPerPage) { - pageNumbers.push(i); - } - return pageNumbers; - }; - - getPageNumbers().map((pageNumber, index:number) => { - pagination.push( - - ) - }) - } - - const handlePageChange = (pageNumber:number) => { - setCurrentPage(pageNumber); - }; - - const handleListRequest = async(): Promise => { - NProgress.start(); - - if (!userData || !userTokens || !Array.isArray(userTokens)) { - console.log("No user data or tokens"); - - NProgress.done(); - return; - } - - if (preferredList) { - if ((userData as any)[preferredList + "Id"] && userTokens?.find((token) => { return token.id === preferredList })?.accessToken) { - const data = await (await axios.post(`/api/fetchEntry`, { - provider: preferredList, - userId: (userData as any)[preferredList + "Id"], - accessToken: userTokens?.find((token) => { return token.id === preferredList })?.accessToken, - mediaId: preferredList === "anilist" ? media.id : media.mappings.find((data) => { return data.providerId === preferredList })?.id ?? "" - })).data as Entry; - - NProgress.done(); - return data; - } - } else { - console.log("No preferred list"); - } - - NProgress.done(); - }; - - const listStatus = [ - { - value: "CURRENT", - label: media.type === "ANIME" ? "Currently Watching" : "Currently Reading" - }, - { - value: "PLANNING", - label: media.type === "ANIME" ? "Plan to Watch" : "Plan to Read" - }, - { - value: "COMPLETED", - label: "Completed" - }, - { - value: "PAUSED", - label: "Paused" - }, - { - value: "DROPPED", - label: "Dropped" - }, - { - value: "REPEATING", - label: "Repeating" - } - ]; - - const saveEntry = async() => { - NProgress.start(); - - const listEntries = { - status: status, - score: Number((document.querySelector("#score") as HTMLInputElement).value), - progress: Number((document.querySelector("#progress") as HTMLInputElement).value), - startedAt: String((document.querySelector("#startDate") as HTMLInputElement).value), - completedAt: String((document.querySelector("#finishDate") as HTMLInputElement).value), - repeat: Number((document.querySelector("#repeats") as HTMLInputElement).value), - notes: String((document.querySelector("#notes") as HTMLInputElement).value), - }; - - if (media.type === Type.MANGA) { - Object.assign(listEntries, { - progressVolumes: Number((document.querySelector("#progressVolumes") as HTMLInputElement).value), - }); - } - - if (Number.isNaN(listEntries.score)) { - listEntries.score = listData.score; - } - if (Number.isNaN(listEntries.progress)) { - listEntries.progress = listData.progress; - } - if (Number.isNaN(listEntries.repeat)) { - listEntries.repeat = listData.repeat; - } - if (!isValidDate(listEntries.startedAt)) { - Object.assign(listEntries, { startedAt: listData.startedAt }); - } - if (!isValidDate(listEntries.completedAt)) { - Object.assign(listEntries, { completedAt: listData.completedAt }); - } - - if (!Array.isArray(userTokens)) { - NProgress.done(); - setShowList(false); - return; - } - - Object.assign(listData, { - status: listEntries.status, - score: listEntries.score, - progress: listEntries.progress, - startedAt: listEntries.startedAt, - completedAt: listEntries.completedAt, - repeat: listEntries.repeat, - notes: listEntries.notes - }) - - if (media.type === Type.MANGA) { - Object.assign(listData, { - progressVolumes: (listEntries as any).progressVolumes - }) - } - - if (preferredList === "anilist") { - const token = userTokens?.find((token) => { return token.id === "anilist" })?.accessToken; - const data = await (await axios.post(`/api/saveEntry`, { - provider: "anilist", - userId: userData.anilistId, - accessToken: token, - entry: listData - })).data as Entry; - - NProgress.done(); - - setShowList(false); - return data; - } - if (preferredList === "mal") { - const token = userTokens?.find((token) => { return token.id === "mal" })?.accessToken; - const data = await (await axios.post(`/api/saveEntry`, { - provider: "mal", - userId: userData.malId, - accessToken: token, - entry: listEntries - })).data as Entry; - - NProgress.done(); - - setShowList(false); - return data; - } - if (preferredList === "simkl") { - const token = userTokens?.find((token) => { return token.id === "simkl" })?.accessToken; - const data = await (await axios.post(`/api/saveEntry`, { - provider: "simkl", - userId: userData.simklId, - accessToken: token, - entry: listEntries - })).data as Entry; - - NProgress.done(); - - setShowList(false); - return data; - } - } - - return ( - <> - - {media.title.english ?? media.title.romaji ?? media.title.native ?? ""} - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - - - -
    - {`${(media.title.english - -
    -
    - {media.title.english ?? media.title.romaji ?? media.title.native} - {media.title.romaji} - {media.title.native} -
    -
    -
    - - - -
    -
    - -
    -
    -
    -
    -
    -
    - - - - - {media.averageRating} -
    -
    - {media.rating?.anilist && media.rating.anilist != 0 ? ( -
    - AniList - {media.rating.anilist} -
    - ) : null} - {media.rating?.mal && media.rating.mal != 0 ? ( -
    - MAL - {media.rating.mal} -
    - ) : null} - {media.rating?.kitsu && media.rating.kitsu != 0 ? ( -
    - Kitsu - {media.rating.kitsu} -
    - ) : null} - {media.rating?.simkl && media.rating.simkl != 0 ? ( -
    - Simkl - {media.rating.simkl} -
    - ) : null} -
    -
    -
    - - - - - {formatCompactNumber(Math.round(media.averagePopularity))} - -
    -
    -
    -
    -
    - {media.genres.slice(0, 7).map((genre, index:number) => { - return ( - {genre.toUpperCase()} - ) - })} -
    - {media.type === Type.ANIME && (media as Anime).season ? ( - - {(media as Anime).season === Season.WINTER ? ( - - - - - - - - ) : (media as Anime).season === Season.SPRING ? ( - - - - - - - ) : (media as Anime).season === Season.SUMMER ? ( - - - - - - - - - - - - ) : (media as Anime).season === Season.FALL ? ( - - - - - ) : ""} - {capitalize((media as Anime).season)} {media.year ?? "?"} - - ) : ""} -
    -
    -
    { - setShowDescription(!showDescription) - }}> -
    -
    -
    - {!showDescription ? ( -
    - Show more -
    - ) : ( -
    - Show less -
    - )} -
    -
    -
    - {/* Select tabs? */} -
    -
    -
    - {media.status ? ( -
    - Status -
    - - {capitalize(media.status)} - -
    -
    - ) : null} - {(media as Anime).trailer ? ( -
    - Trailer -
    - - Link - -
    -
    - ) : null} - {media.countryOfOrigin ? ( -
    - Country -
    - - {media.countryOfOrigin} - -
    -
    - ) : null} -
    - Genres -
    - {media.genres.map((genre, index:number) => { - return ( - - {genre} - - ) - })} -
    -
    -
    - {media.synonyms.length > 0 ? ( -
    - Alternate Titles -
    - {media.title.english ? ( - - {media.title.english} - - ) : null} - {media.title.romaji ? ( - - {media.title.romaji} - - ) : null} - {media.title.native ? ( - - {media.title.native} - - ) : null} - {media.synonyms.map((synonym, index:number) => { - return ( - - {synonym} - - ) - })} -
    -
    - ) : null} - {media.tags.length > 0 ? ( -
    - Tags -
    - {media.tags.map((tag, index:number) => { - return ( - - {tag} - - ) - })} -
    -
    - ) : null} -
    -
    -
    - { - setCurrentSearch((document.getElementById("search") as HTMLInputElement).value); - }} /> -
    - -
    -
    - {media.type === "ANIME" ? ( -
    - {subDub === "sub" ? "Subbed" : "Dubbed"} -
    { - setSubDub(subDub === "sub" ? "dub" : "sub"); - }}>
    -
    - ) : null} - state.isFocused ? "border-main-300" : "border-none" - }} className="z-50" styles={{ - container: (baseStyles, state) => ({ - ...baseStyles, - color: "white", - backgroundColor: "#141414", - border: "none", - borderRadius: "0.25rem", - zIndex: "50", - }), - control: (baseStyles, state) => ({ - ...baseStyles, - color: "white", - backgroundColor: "#141414", - border: "none", - }), - input: (baseStyles, state) => ({ - ...baseStyles, - color: "white", - backgroundColor: "#141414", - border: "none" - }), - menu: (baseStyles, state) => ({ - ...baseStyles, - color: "white", - backgroundColor: "#333333", - border: "none", - zIndex: "50", - }), - menuList: (baseStyles, state) => ({ - ...baseStyles, - width: "100%", - height: "100%", - zIndex: "50", - }), - noOptionsMessage: (baseStyles, state) => ({ - ...baseStyles, - color: "white", - }), - placeholder: (baseStyles, state) => ({ - ...baseStyles, - color: "white", - }), - singleValue: (baseStyles, state) => ({ - ...baseStyles, - color: "white", - height: "100%", - position: "relative", - top: "10%", - overflow: "initial", - zIndex: "50", - }), - valueContainer: (baseStyles, state) => ({ - ...baseStyles, - color: "white" - }), - option: (baseStyles, state) => ({ - ...baseStyles, - backgroundColor: "#333333", - color: "white", - zIndex: "50", - transition: "0.1s all", - cursor: "pointer", - ":hover": { - backgroundColor: "#1f1f1f" - }, - ":active": { - color: "white", - backgroundColor: "#1f1f1f" - }, - lineHeight: "1.25rem", - height: "100%" - }), - indicatorSeparator: (baseStyles, state) => ({ - ...baseStyles, - display: "none" - }), - dropdownIndicator: (baseStyles, state) => ({ - ...baseStyles, - backgroundColor: "none", - color: "white", - transition: "0.1s all", - ":hover": { - color: "rgba(255, 255, 255, 0.7)" - }, - ":active": { - color: "rgba(255, 255, 255, 0.5)", - } - }), - }} defaultValue={listStatus.map((el) => { - if (String(el.value) === listData.status) { - return el; - } - })} isSearchable={false} name="chapter_list" onChange={(data) => { - setStatus(data?.value ?? ""); - }} /> -
    -
    -
    - - Score - -
    - - - - - - - - - - -
    - -
    -
    -
    -
    - - {media.type === Type.ANIME ? "Episode Progress" : "Chapter Progress"} - -
    - - - - - - - - - - -
    - -
    -
    -
    - {media.type === Type.MANGA ? ( -
    - - Volume Progress - -
    - - - - - - - - - - -
    - -
    -
    -
    - ) : null} -
    - - Start Date - -
    -
    - -
    -
    -
    -
    - - Finish Date - -
    -
    - -
    -
    -
    -
    - - Repeats - -
    - - - - - - - - - - -
    - -
    -
    -
    -
    - - Notes - -
    - -
    -
    -
    -
    -
    -
    -
    - - ) -} - -export const getServerSideProps = async ({ query }: { query: { id: string } }) => { - const { id } = query; - - const media = await (await axios.get(`${env.BACKEND_URL}/info?id=${id}&apikey=${env.API_KEY}`)).data as Anime | Manga; - const relations = await (await axios.get(`${env.BACKEND_URL}/relations?id=${id}&apikey=${env.API_KEY}`)).data as Anime | Manga; - - const contentType = media.type === Type.ANIME ? "episodes" : "chapters"; - const content = await (await axios.get(`${env.BACKEND_URL}/${contentType}?id=${id}&apikey=${env.API_KEY}`)).data as EpisodeData[] | ChapterData[]; - - if (media.type === Type.ANIME) { - const episodeCovers = await (await axios.get(`${env.BACKEND_URL}/episode-covers?id=${id}&apikey=${env.API_KEY}`)).data as { episode: number, img: string }[]; - - for (let i = 0; i < content.length; i++) { - const episodes = (content as EpisodeData[])[i]?.episodes ?? []; - for (let j = 0; j < episodes.length; j++) { - const episodeNumber = (episodes[j]?.number ?? 0); - for (let k = 0; k < episodeCovers.length; k++) { - if (episodeCovers[k]?.episode === episodeNumber) { - if (!episodes[j]?.img) { - Object.assign((content as EpisodeData[])[i]?.episodes[j] ?? {}, { img: episodeCovers[k]?.img }); - } - break; - } - } - } - } - - return { - props: { - media, - relations, - content - }, - }; - } else { - return { - props: { - media, - relations, - content - }, - }; - } -}; - -export default Info; - -interface Props { - media: Anime | Manga; - relations: AnimeRelation[] | MangaRelation[]; - content: EpisodeData[] | ChapterData[]; -} \ No newline at end of file diff --git a/anify-frontend/src/pages/login.tsx b/anify-frontend/src/pages/login.tsx deleted file mode 100644 index 1368dd2..0000000 --- a/anify-frontend/src/pages/login.tsx +++ /dev/null @@ -1,375 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import axios from "axios"; -import { type GetServerSideProps, type NextPage } from "next"; -import Head from "next/head"; -import Link from "next/link"; -import { useEffect, useState } from "react"; -import { useStore } from "zustand"; -import Footer from "~/components/footer"; -import Navbar from "~/components/navbar"; -import Sidebar from "~/components/sidebar"; -import { env } from "~/env.mjs"; -import { usePreferredList, useTokens, useUserData } from "~/store/store"; -import { type UserData, type AuthProviders, type UserTokens } from "~/types"; - -const Login: NextPage = ({ login, user, token, provider, providers, redirect, error }) => { - const [createAccount, setCreateAccount] = useState(false); - - const userData = useStore(useUserData, ((state: any) => state.userData as UserData)); - const userTokens = useStore(useTokens, ((state: any) => state.tokens as UserTokens[])); - - const [showError, setShowError] = useState(true); - - useEffect(() => { - if (redirect) { - if (userData) { - window.location.replace(`/login?token=${token ?? ""}&provider=${provider ?? ""}&id=${userData.id}`); - } - } else { - if (token && provider) { - useUserData.setState({ userData }); - - if (Array.isArray(userTokens)) { - userTokens?.push({ id: provider, accessToken: token }); - } - useTokens.setState({ tokens: [...(userTokens ?? []), { id: provider, accessToken: token }] }); - usePreferredList.setState({ preferredList: provider }); - - window.location.replace(`/login?id=${user?.id ?? ""}`); - } - } - if (user && !userData) { - useUserData.setState({ userData: user }); - } - }) - - return ( - <> - - {"Login"} - - - - - - - - - - - - - - - - - - -
    -
    - {login ? ( -
    -

    {createAccount ? "Create Account" : "Login"}

    -
    { - const username = String((event.target as any)[0].value); - const password = String((event.target as any)[1].value); - - if (createAccount) { - window.location.href = "/login?register=true&username=" + username + "&password=" + password; - } else { - window.location.href = "/login?login=true&username=" + username + "&password=" + password; - } - event.preventDefault(); - }}> - - - -
    - {!createAccount ? ( - - ) : } -
    - ) : ( -
    -

    Providers

    -
    -
    - {providers?.map((p, index) => ( -
    -
    - {p.name} -
    - {provider === p.id ? : - p.id === "anilist" && user?.anilistId && Array.isArray(userTokens) && userTokens?.find((provider) => provider.id === p.id) ? Linked! : - p.id === "mal" && user?.malId && Array.isArray(userTokens) && userTokens?.find((provider) => provider.id === p.id) ? Linked! : - p.id === "simkl" && user?.simklId && Array.isArray(userTokens) && userTokens?.find((provider) => provider.id === p.id) ? Linked! : - Link} -
    - ))} -
    -
    - Note: If you end up linking a provider you've never linked before, please logout and log back in! -
    -
    - Logout -
    - )} - {error ? ( -
      -
    1. -
      Error
      - {error} - -
    2. -
    - ) : null} -
    -
    -
    - - ) -}; - -export const getServerSideProps: GetServerSideProps = async ({ query }) => { - const { AUTH_URL } = env; - - const handleLogin = async (username: string, password: string) => { - try { - const response = await axios.post(`${AUTH_URL}/login`, { username, password }).catch((err) => { - return { - data: err.response.data as { error: string } - } - }); - - if (response.data?.error) return response.data as { error: string }; - - const userId = response.data?.id as string | undefined; - return userId; - } catch (error) { - console.error(error); - return null; - } - }; - - const handleRegister = async (username: string, password: string) => { - try { - const response = await axios.post(`${AUTH_URL}/create-user`, { username, password }).catch((err) => { - return { - data: err.response.data as { error: string } - } - }); - - if (response.data?.error) return response.data as { error: string }; - - const userId = response.data?.id as string | undefined; - return userId; - } catch (error) { - console.error(error); - return null; - } - }; - - const handleUpdateUser = async (id: string, providerId: string, provider: string) => { - try { - if (provider === "anilist") { - const response = await axios.post(`${AUTH_URL}/update-user`, { id, anilistId: providerId }); - const userData = response.data as UserData; - return userData; - } else if (provider === "mal") { - const response = await axios.post(`${AUTH_URL}/update-user`, { id, malId: providerId }); - const userData = response.data as UserData; - return userData; - } else { - return null; - } - } catch (error) { - console.error(error); - return null; - } - }; - - const handleProvider = async (token: string, provider: string) => { - if (provider === "anilist") { - const userOptions = { - uri: "https://graphql.anilist.co", - method: "POST", - data: { - query: ` - query { - Viewer { - id - name - } - } - `, - variables: { - } - } - }; - - const data = await (await axios(userOptions.uri, { - data: JSON.stringify(userOptions.data), - method: userOptions.method, - headers: { - "Authorization": `Bearer ${token}`, - "Content-Type": "application/json", - "Accept": "application/json" - } - })).data as { - data: { - Viewer: { - id: number; - name: string; - } - } - }; - - const user = data.data.Viewer; - return user; - } - if (provider === "mal") { - const userOptions = { - uri: "https://api.myanimelist.net/v2/users/@me?fields=anime_statistics", - method: "GET", - }; - - const data = await (await axios(userOptions.uri, { - method: userOptions.method, - headers: { - "Authorization": `Bearer ${token}`, - "Content-Type": "application/json", - "Accept": "application/json" - } - })).data as { - id: number; - name: string; - gender: string; - birthday: string; - location: string; - joined_at: string; - anime_statistics: { - num_items_watching: number; - num_items_completed: number; - num_items_on_hold: number; - num_items_dropped: number; - num_items_plan_to_watch: number; - num_items: number; - num_days_watched: number; - num_days_watching: number; - } - }; - - return data; - } - }; - - try { - if (query.login) { - const { username, password } = query; - const userId = await handleLogin(String(username), String(password)); - - if (!userId || (userId as any).error) { - return { - props: { - login: true, - error: String((userId as any).error ?? "An error occurred while logging in.") - }, - }; - } - - query.id = String(userId); - } else if (query.register) { - const { username, password } = query; - const userId = await handleRegister(String(username), String(password)).catch(() => null); - - if (!userId || (userId as any).error) { - return { - props: { - login: true, - error: String((userId as any).error ?? "An error occurred while logging in.") - }, - }; - } - - query.id = String(userId); - } - - const providers = (await axios.get(`${AUTH_URL}/providers`)).data as AuthProviders[]; - - if (query.token && typeof query.token === "string") { - const { token, provider } = query; - - const userData = await handleProvider(token, String(provider)); - if (query.id) { - const updatedUser = await handleUpdateUser(String(query.id), String(userData?.id), String(provider)); - - return { - props: { - user: updatedUser ?? null, - token, - provider, - providers - }, - }; - } else { - return { - props: { - redirect: true, - token, - provider, - providers - }, - }; - } - } - - if (!query.id) { - // Login - return { - props: { - login: true - } - } - } - - const response = await axios.get(`${AUTH_URL}/user?id=${String(query.id)}`); - const userData = response.data as UserData; - - return { - props: { - user: userData ?? null, - token: query.token ?? null, - provider: query.provider ?? null, - providers, - }, - }; - } catch (error) { - console.error(error); - return { - props: {}, - }; - } -}; - -export default Login; - -interface Props { - user?: UserData; - token?: string; - provider?: string; - providers: AuthProviders[]; - redirect?: boolean; - login?: boolean; - error?: string; -} diff --git a/anify-frontend/src/pages/logout.tsx b/anify-frontend/src/pages/logout.tsx deleted file mode 100644 index 0a93783..0000000 --- a/anify-frontend/src/pages/logout.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { type NextPage } from "next"; -import Head from "next/head"; -import { useEffect } from "react"; -import Footer from "~/components/footer"; -import Navbar from "~/components/navbar"; -import Sidebar from "~/components/sidebar"; -import { useTokens, useUserData } from "~/store/store"; - -const Logout: NextPage = () => { - useEffect(() => { - useUserData.setState({ userData: null }); - useTokens.setState({ tokens: [] }); - - window.location.href = "/"; - }) - - return ( - <> - - {"Logout"} - - - - - - - - - - - - - - - - - - -
    -
    -
    -

    Logging out...

    -
    -
    -
    -
    - - ) -}; - -export default Logout; \ No newline at end of file diff --git a/anify-frontend/src/pages/manga.tsx b/anify-frontend/src/pages/manga.tsx deleted file mode 100644 index ab0c628..0000000 --- a/anify-frontend/src/pages/manga.tsx +++ /dev/null @@ -1,159 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import axios from "axios"; - -import { type GetServerSideProps, type NextPage } from "next"; -import Sidebar from "~/components/sidebar"; - -import { env } from "~/env.mjs"; -import Footer from "~/components/footer"; -import { type Seasonal, type Manga, type ReadHistory, Format } from "~/types"; -import Slideshow from "~/components/slideshow"; -import Navbar from "~/components/navbar"; -import LargeSlideshow from "~/components/largeSlideshow"; -import Head from "next/head"; -import { useEffect, useState } from "react"; -import { useStore } from "zustand"; -import { useReadHistory } from "~/store/store"; -import { Swiper, SwiperSlide } from "swiper/react"; -import Link from "next/link"; - -const Manga: NextPage = ({ seasonal, recent }) => { - const [readHistory, setReadHistory] = useState([]); - - const storedReadHistory = useStore(useReadHistory, ((state: any) => state.readHistory as ReadHistory[])); - - useEffect(() => { - const uniqueReadHistoryMap = new Map(); - - for (const history of storedReadHistory) { - if (history.format === Format.NOVEL) continue; - uniqueReadHistoryMap.set(history.mediaId, history); - } - - const newReadHistory = Array.from(uniqueReadHistoryMap.values()); - setReadHistory(newReadHistory); - }, [storedReadHistory]); - - return ( - <> - - {"Manga"} - - - - - - - - - - - - - - - - - - -
    -
    -
    - -
    - {readHistory?.length > 0 ? ( -
    -

    Continue Reading

    - - {readHistory.map((media, index: number) => { - return ( - -
    -
    -
    - - {(media.title?.english - -
    -
    - - - - - - - - - - -
    -
    -
    -
    -
      -
    • {media.title?.english ?? media.title?.romaji ?? media.title?.native ?? "N/A"}
    • -
    • - {media.chapterNumber ? Chapter {media.chapterNumber} : null} -
    • -
    -
    -
    -
    -
    - ) - })} -
    -
    - ) : null} -
    -

    Recent Chapters

    - -
    -
    -

    Popular

    - -
    -
    -

    Highest Rated

    - -
    -
    -
    -
    - - ); -}; - -export const getServerSideProps: GetServerSideProps = async () => { - const seasonal = (await axios.get(String(env.BACKEND_URL) + "/seasonal?type=manga&fields=[id,description,bannerImage,coverImage,title,genres,format,averageRating,episodes,chapters,year]&apikey=" + String(env.API_KEY))).data as Seasonal; - const recent = (await axios.get(String(env.BACKEND_URL) + "/recent?type=manga&apikey=" + String(env.API_KEY))).data as Manga[]; - - return { - props: { - seasonal, - recent, - }, - }; -}; - -export default Manga; - -interface Props { - seasonal?: Seasonal; - recent?: Manga[]; -} diff --git a/anify-frontend/src/pages/novels.tsx b/anify-frontend/src/pages/novels.tsx deleted file mode 100644 index 95f536a..0000000 --- a/anify-frontend/src/pages/novels.tsx +++ /dev/null @@ -1,161 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import axios from "axios"; - -import { type GetServerSideProps, type NextPage } from "next"; -import Sidebar from "~/components/sidebar"; - -import { env } from "~/env.mjs"; -import Footer from "~/components/footer"; -import { type Seasonal, type Manga, type ReadHistory, Format } from "~/types"; -import Slideshow from "~/components/slideshow"; -import Navbar from "~/components/navbar"; -import LargeSlideshow from "~/components/largeSlideshow"; -import Head from "next/head"; -import { useEffect, useState } from "react"; -import { useStore } from "zustand"; -import { useReadHistory } from "~/store/store"; -import { Swiper, SwiperSlide } from "swiper/react"; -import Link from "next/link"; - -const Novel: NextPage = ({ seasonal, recent }) => { - const [readHistory, setReadHistory] = useState([]); - - const storedReadHistory = useStore(useReadHistory, ((state: any) => state.readHistory as ReadHistory[])); - - useEffect(() => { - const uniqueReadHistoryMap = new Map(); - - for (const history of storedReadHistory) { - if (history.format != Format.NOVEL) continue; - uniqueReadHistoryMap.set(history.mediaId, history); - } - - const newReadHistory = Array.from(uniqueReadHistoryMap.values()); - setReadHistory(newReadHistory); - }, [storedReadHistory]); - - return ( - <> - - {"Novels"} - - - - - - - - - - - - - - - - - - -
    -
    -
    - -
    - {readHistory?.length > 0 ? ( -
    -

    Continue Reading

    - - {readHistory.map((media, index: number) => { - return ( - -
    -
    -
    - - {(media.title?.english - -
    -
    - - - - - - - - - - -
    -
    -
    -
    -
      -
    • {media.title?.english ?? media.title?.romaji ?? media.title?.native ?? "N/A"}
    • -
    • - {media.chapterNumber ? Chapter {media.chapterNumber} : null} -
    • -
    -
    -
    -
    -
    - ) - })} -
    -
    - ) : null} - {(recent ?? []).length > 0 ? ( -
    -

    Recent Chapters

    - -
    - ) : null} -
    -

    Popular

    - -
    -
    -

    Highest Rated

    - -
    -
    -
    -
    - - ); -}; - -export const getServerSideProps: GetServerSideProps = async () => { - const seasonal = (await axios.get(String(env.BACKEND_URL) + "/seasonal?type=novel&fields=[id,description,bannerImage,coverImage,title,genres,format,averageRating,episodes,chapters,year]&apikey=" + String(env.API_KEY))).data as Seasonal; - const recent = (await axios.get(String(env.BACKEND_URL) + "/recent?type=novel&apikey=" + String(env.API_KEY))).data as Manga[]; - - return { - props: { - seasonal, - recent, - }, - }; -}; - -export default Novel; - -interface Props { - seasonal?: Seasonal; - recent?: Manga[]; -} diff --git a/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx b/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx deleted file mode 100644 index 2a03ac9..0000000 --- a/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx +++ /dev/null @@ -1,656 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import axios from "axios"; -import { type NextPage, type GetServerSideProps } from "next"; -import Link from "next/link"; -import { useEffect, useState } from "react"; -import { SettingsPanel } from "~/components/settingsPanel"; -import { env } from "~/env.mjs"; -import { type Page, type ChapterData, type Manga, Format, type MixdropResponse, type ReadHistory } from "~/types"; -import { ChaptersPanel } from "~/components/chaptersPanel"; -import { MangaPage } from "~/components/page"; -import Head from "next/head"; -import { useFontSize, useFontWidth, useHeaderBackground, usePageSize, useReadHistory } from "~/store/store"; -import { useStore } from "zustand"; - -const Read: NextPage = ({ chapterNumber, chapterSelector, chapters, downloadLink, mixdrop, media, nextChapter, pages, previousChapter, readId, provider }) => { - const [showNavbar, setShowNavbar] = useState(true); - const [prevScrollPos, setPrevScrollPos] = useState(0); - - const [open, setOpen] = useState(false); - const [showChapters, setShowChapters] = useState(false); - - const fontSize = useStore(useFontSize, ((state: any) => state.fontSize as string)); - const pageSize = useStore(usePageSize, ((state: any) => state.pageSize as string)); - const fontWidth = useStore(useFontWidth, ((state: any) => state.fontWidth as string)); - const headerBackground = useStore(useHeaderBackground, ((state: any) => state.headerBackground as boolean)); - - const readHistory = useStore(useReadHistory, ((state: any) => state.readHistory as ReadHistory[])); - - const updateSize = (fontSize: string, lineHeight: string) => { - useFontSize.setState({ fontSize: `${fontSize} ${lineHeight}` }) - - document.documentElement.style.setProperty("--font-size", fontSize); - document.documentElement.style.setProperty("--font-height", lineHeight); - }; - - const updatePageSize = (value?: string) => { - usePageSize.setState({ pageSize: value ?? pageSize }) - - document.documentElement.style.setProperty("--page-size", value ?? ""); - }; - - const updateWidth = (value?: string) => { - useFontWidth.setState({ fontWidth: value ?? fontWidth }) - - document.documentElement.style.setProperty("--font-weight", value ?? ""); - }; - - const updateHeader = (value?: boolean) => { - useHeaderBackground.setState({ headerBackground: value }) - - const header: HTMLElement | null = document.querySelector(".header"); - if (header) { - if (value) { - header.classList.add("bg-[#181818d2]"); - header.style.backdropFilter = "saturate(180%) blur(10px)"; - (header.style as any)["-webkit-backdrop-filter"] = "saturate(180%) blur(10px)"; - } else { - header.classList.remove("bg-[#181818d2]"); - header.style.backdropFilter = ""; - (header.style as any)["-webkit-backdrop-filter"] = ""; - } - } - }; - - useEffect(() => { - updateSize(fontSize?.split(" ")[0] ?? "", fontSize?.split(" ")[1] ?? ""); - updateWidth(fontWidth); - updateHeader(headerBackground); - - let currentReadHistory: number | undefined = undefined; - - for (let i = 0; i < (readHistory ?? []).length; i++) { - if (readHistory?.[i]?.chapterNumber != chapterNumber && readHistory?.[i]?.mediaId === media.id) { - readHistory?.splice(i, 1); - } - } - - for (let i = 0; i < (readHistory ?? []).length; i++) { - if (readHistory?.[i]?.chapterNumber === chapterNumber && readHistory?.[i]?.mediaId === media.id) { - currentReadHistory = i; - } - } - - if (currentReadHistory === undefined) { - const newReadHistory = { - chapterNumber, - mediaId: media.id, - coverImage: media.coverImage ?? "", - title: media.title, - readId, - providerId: provider, - format: media.format - } as ReadHistory; - - currentReadHistory = readHistory?.length; - - readHistory?.unshift(newReadHistory); - } else { - const temp = readHistory?.[currentReadHistory]; - readHistory?.splice(currentReadHistory, 1); - - Object.assign(temp ?? {}, { - chapterNumber, - mediaId: media.id, - coverImage: media.coverImage ?? "", - title: media.title, - readId, - providerId: provider, - format: media.format - }); - - temp ? readHistory?.unshift(temp) : null; - } - - useReadHistory.setState({ readHistory }); - - const handleScroll = () => { - const currentScrollPos = window.pageYOffset; - setShowNavbar(prevScrollPos > currentScrollPos || currentScrollPos <= 0); - setPrevScrollPos(currentScrollPos); - }; - - window.addEventListener("scroll", handleScroll); - return () => { - window.removeEventListener("scroll", handleScroll); - }; - }, [prevScrollPos]); - - return ( - <> - - {"Chapter " + String(chapterNumber) + " - " + (media.title.english ?? media.title.romaji ?? media.title.native ?? "")} - - - - - - - - - - - - - - - - -
    - {media.format === Format.NOVEL ? ( -
    -
    -
    - - - -
    -
    -
    -
    -
    - - - - - - - - - - - - - - -
    -
    -
    { - setOpen(!open); - setShowChapters(false); - }}> - - - -
    -
    { - setShowChapters(!showChapters); - setOpen(false); - }} className="bg-[hsla(0,0%,76%,0)] rounded-sm p-[5px] w-[32px] h-[32px] flex justify-center items-center ml-auto mr-[12px] cursor-pointer hover:bg-[hsla(0,0%,76%,.2)] transition-all duration-200"> - - - - - -
    - Font Size
    ", - iconID: "fontSizeIcon", - open: "size", - }, - { - html: "
    Font Width
    ", - iconID: "fontWidthIcon", - open: "width", - }, - { - html: "
    Settings
    ", - iconID: "configIcon", - open: "config", - }, - ], - }, - { - id: "size", - selectableScene: true, - heading: { - html: "
    Font Size
    ", - open: "size", - hideSubArrow: true, - }, - items: [ - { - html: `
    Small
    `, - callback: () => updateSize("0.875rem", "1.25rem"), - highlightable: true, - selected: fontSize === "0.875rem 1.25rem", - }, - { - html: `
    Base
    `, - callback: () => updateSize("1rem", "1.5rem"), - highlightable: true, - selected: fontSize === "1rem 1.5rem", - }, - { - html: `
    Large
    `, - callback: () => updateSize("1.125rem", "1.75rem"), - highlightable: true, - selected: fontSize === "1.125rem 1.75rem", - }, - { - html: `
    XL
    `, - callback: () => updateSize("1.25rem", "1.75rem"), - highlightable: true, - selected: fontSize === "1.25rem 1.75rem", - }, - { - html: `
    4XL
    `, - callback: () => updateSize("2.25rem", "2.5rem"), - highlightable: true, - selected: fontSize === "2.25rem 2.5rem", - }, - ], - }, - { - id: "width", - selectableScene: true, - heading: { - html: "
    Font Width
    ", - open: "width", - hideSubArrow: true, - }, - items: [ - { - html: `
    Thin
    `, - callback: () => updateWidth("100"), - highlightable: true, - selected: fontWidth === "100", - }, - { - html: `
    Extra-light
    `, - callback: () => updateWidth("200"), - highlightable: true, - selected: fontWidth === "200", - }, - { - html: `
    Light
    `, - callback: () => updateWidth("300"), - highlightable: true, - selected: fontWidth === "300", - }, - { - html: `
    Normal
    `, - callback: () => updateWidth("400"), - highlightable: true, - selected: fontWidth === "400", - }, - { - html: `
    Medium
    `, - callback: () => updateWidth("500"), - highlightable: true, - selected: fontWidth === "500", - }, - { - html: `
    Semi-bold
    `, - callback: () => updateWidth("600"), - highlightable: true, - selected: fontWidth === "600", - }, - { - html: `
    Bold
    `, - callback: () => updateWidth("700"), - highlightable: true, - selected: fontWidth === "700", - }, - { - html: `
    Extra Bold
    `, - callback: () => updateWidth("800"), - highlightable: true, - selected: fontWidth === "800", - }, - { - html: `
    Black
    `, - callback: () => updateWidth("900"), - highlightable: true, - selected: fontWidth === "900", - }, - ], - }, - { - id: "config", - heading: { - text: "
    Settings
    ", - back: true, - }, - items: [ - { - html: '

    Header Background

    ', - customId: "header", - toggle: true, - toggleOn: () => updateHeader(true), - toggleOff: () => updateHeader(false), - on: headerBackground - } - ], - }, - ] - } - /> - -
    -
    -
    -
    -
    - - {provider === "JNovels" ? "No data available! Visit the open tab to download the novel. If you can't see it, please allow pop-ups and refresh the page." : ""} - -
    -
    - ) : ( -
    -
    -
    - - - -
    -
    -
    - {downloadLink?.result[mixdrop ?? ""]?.url ? ( - - - - - - - - ) : null} -
    -
    - - - - - - - - - - - - - - -
    -
    -
    { - setOpen(!open); - setShowChapters(false); - }}> - - - -
    -
    { - setShowChapters(!showChapters); - setOpen(false); - }} className="bg-[hsla(0,0%,76%,0)] rounded-sm p-[5px] w-[32px] h-[32px] flex justify-center items-center ml-auto mr-[12px] cursor-pointer hover:bg-[hsla(0,0%,76%,.2)] transition-all duration-200"> - - - - - -
    - Page Size
    ", - iconID: "pageSizeIcon", - open: "size", - }, - { - html: "
    Settings
    ", - iconID: "configIcon", - open: "config", - }, - ], - }, - { - id: "size", - selectableScene: true, - heading: { - html: "
    Page Size
    ", - open: "size", - hideSubArrow: true, - }, - items: [ - { - html: `
    1/4
    `, - callback: () => updatePageSize("25vw"), - highlightable: true, - selected: pageSize === "25vw", - }, - { - html: `
    1/2
    `, - callback: () => updatePageSize("50vw"), - highlightable: true, - selected: pageSize === "50vw", - }, - { - html: `
    Full
    `, - callback: () => updatePageSize("100vw"), - highlightable: true, - selected: pageSize === "100vw", - }, - ], - }, - { - id: "config", - heading: { - text: "
    Settings
    ", - back: true, - }, - items: [ - { - html: '

    Header Background

    ', - customId: "header", - toggle: true, - toggleOn: () => updateHeader(true), - toggleOff: () => updateHeader(false), - on: headerBackground - } - ], - }, - ] - } - /> - -
    -
    -
    - {pages && typeof pages !== "string" && pages.length > 0 ? pages.map((page, index) => ( - - )) : ( -
    -
    -
    -
    No pages found
    -
    Please try a different connector. If this is a bug, please join our Discord and report it.
    -
    - )} -
    -
    - )} -
    - - ) -} - -export const getServerSideProps: GetServerSideProps = async (context) => { - const id: string | string[] | undefined = context.params?.id; - const provider: string | string[] | undefined = context.params?.provider; - const readId: string | string[] | undefined = context.params?.readId; - - if (!id || !provider || !readId) return { notFound: true }; - - const media = (await axios.get(String(env.BACKEND_URL) + "/info/" + String(id) + "?apikey=" + String(env.API_KEY))).data as Manga; - const content = (await axios.get(String(env.BACKEND_URL) + "/chapters/" + String(id) + "?apikey=" + String(env.API_KEY))).data as ChapterData[]; - - let mixdrop = ""; - for (const prov of content) { - if (prov.providerId === provider) { - for (const chapter of prov.chapters) { - if (chapter.id === readId) mixdrop = chapter.mixdrop ?? ""; - } - } - } - - let downloadLink: MixdropResponse | null = null; - - if (mixdrop) { - downloadLink = await (await axios.post(String(env.BACKEND_URL) + "/pages-download?apikey=" + String(env.API_KEY), { - id: mixdrop - })).data as MixdropResponse; - } - - content.reverse(); - - let nextChapter = ""; - let previousChapter = ""; - let chapterNumber = -1; - let chapterTitle = ""; - - const chapterSelector = []; - - for (let i = 0; i < content.length; i++) { - const providerChap = content[i]; - for (let j = 0; j < (providerChap?.chapters ?? []).length; j++) { - const chapter = providerChap?.chapters[j]; - - if (chapter?.id === readId) { - chapterTitle = chapter?.title ?? ""; - chapterNumber = chapter.number ?? i; - } - if (providerChap?.providerId.toLowerCase() === (provider as string).toLowerCase()) { - const title = chapter?.title; - chapterSelector.push({ - title: title ?? "Chapter " + String(i + 1), - number: chapter?.number, - length: providerChap?.providerId, - url: `/read/${id as string ?? ""}/${provider as string ?? ""}/${encodeURIComponent(chapter?.id ?? "")}`, - selected: chapter?.id === readId, - }); - if (chapter?.id === readId) { - if (j < providerChap.chapters.length - 1) { - nextChapter = `/read/${id as string ?? ""}/${provider as string ?? ""}/${encodeURIComponent( - providerChap.chapters[j + 1]?.id ?? readId - )}`; - } else { - nextChapter = `/read/${id as string ?? ""}/${provider as string ?? ""}/${encodeURIComponent( - readId - )}`; - } - if (j > 0) { - previousChapter = `/read/${id as string ?? ""}/${provider as string ?? ""}/${encodeURIComponent( - providerChap.chapters[j - 1]?.id ?? readId - )}`; - } else { - previousChapter = `/read/${id as string ?? ""}/${provider as string ?? ""}/${encodeURIComponent( - readId - )}`; - } - } - } - } - } - - const pages = await (await axios.post(String(env.BACKEND_URL) + "/pages?apikey=" + String(env.API_KEY), { - chapterNumber, - providerId: provider, - readId, - id - })).data as Page[]; - - if (media.format !== "NOVEL") { - for (let i = 0; i < pages.length; i++) { - if (pages[i]?.headers && Object.keys(pages[i]?.headers ?? {}).length > 0) { - Object.assign(pages[i] ?? {}, { url: `${String(env.IMAGE_PROXY)}?url=${encodeURIComponent(String(pages[i]?.url))}&headers=${encodeURIComponent(JSON.stringify(pages[i]?.headers))}` }) - } - } - } - - return { - props: { - media, - chapters: content, - chapterSelector, - chapterNumber, - pages, - nextChapter, - previousChapter, - readId, - provider: provider as string, - mixdrop, - downloadLink - } - } -} - -export default Read; - -interface Props { - media: Manga; - chapters: ChapterData[]; - chapterSelector: { - title: string; - number: number; - length: string; - url: string; - selected: boolean; - }[]; - chapterNumber: number; - pages: Page[] | string; - nextChapter: string; - previousChapter: string; - readId: string; - provider: string; - mixdrop: string | null; - downloadLink: MixdropResponse | null; -} \ No newline at end of file diff --git a/anify-frontend/src/pages/watch/[id]/[provider]/[watchId]/[subDub].tsx b/anify-frontend/src/pages/watch/[id]/[provider]/[watchId]/[subDub].tsx deleted file mode 100644 index 3d10c29..0000000 --- a/anify-frontend/src/pages/watch/[id]/[provider]/[watchId]/[subDub].tsx +++ /dev/null @@ -1,979 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-unsafe-argument */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { MediaCaptions, MediaFullscreenButton, MediaMuteButton, MediaOutlet, MediaPlayButton, MediaPlayer, MediaSliderThumbnail, MediaSliderValue, MediaTime, MediaTimeSlider, MediaTooltip, MediaVolumeSlider } from "@vidstack/react"; -import axios from "axios"; - -import { type GetServerSideProps, type NextPage } from "next"; -import { useEffect, useRef, useState } from "react"; -import { TextTrack, type MediaPlayerElement } from "vidstack"; - -import "vidstack/styles/defaults.css"; -import styles from "~/styles/watch.module.css" - -import { env } from "~/env.mjs"; -import { capitalize } from "~/helper"; -import { type WatchTime, type Anime, type EpisodeData, type Source } from "~/types"; -import { SettingsPanel } from "~/components/settingsPanel"; -import { ChaptersPanel } from "~/components/chaptersPanel"; -import Head from "next/head"; -import Link from "next/link"; -import { useAutoFullscreen, useAutoNext, useAutoSkip, useSpeed, useSubtitles, useWatchTime } from "~/store/store"; -import { useStore } from "zustand"; - -const Watch: NextPage = ({ episodeNumber, episodeSelector, episodes, media, sources, subtitles, provider, watchId, thumbnails, subDub }) => { - const [src, setSrc] = useState(sources.sources[sources.sources.length - 1]?.url ?? ""); - - const [open, setOpen] = useState(false); - const [showChapters, setShowChapters] = useState(false); - - const watchTime = useStore(useWatchTime, ((state: any) => state.currentTime as WatchTime[])); - const autoSkip = useStore(useAutoSkip, ((state: any) => state.autoSkip as boolean)); - const autoNext = useStore(useAutoNext, ((state: any) => state.autoNext as boolean)); - const autoFullscreen = useStore(useAutoFullscreen, ((state: any) => state.autoFullscreen as boolean)); - const subs = useStore(useSubtitles, ((state: any) => state.subtitles as boolean)); - const speed = useStore(useSpeed, ((state: any) => state.speed as number)); - - const playerRef = useRef(null); - - const banners = media.artwork.filter((x) => x.type === "banner" && x.providerId === "tvdb"); - const playerPoster = banners.length ? banners[Math.floor(Math.random() * banners.length)] : { img: media.bannerImage }; - - useEffect(() => { - addCues(); - - disableSubs(subs ?? false); - changeSpeed(speed ?? 1); - - let currentWatchTime: number | undefined = undefined; - - playerRef.current?.addEventListener("play", ((event) => { - if (playerRef.current?.currentTime != watchTime?.[currentWatchTime ?? 0]?.currentTime) { - Object.assign(playerRef.current ?? {}, { currentTime: watchTime?.[currentWatchTime ?? 0]?.currentTime }); - } - })); - - playerRef.current?.addEventListener("end", ((event) => { - goNext(); - })) - - playerRef.current?.addEventListener("ended", ((event) => { - goNext(); - })) - - playerRef.current?.addEventListener("loaded-data", ((event) => { - if (playerRef.current?.currentTime != watchTime?.[currentWatchTime ?? 0]?.currentTime) { - Object.assign(playerRef.current ?? {}, { currentTime: watchTime?.[currentWatchTime ?? 0]?.currentTime }); - } - })); - - playerRef.current?.subscribe(({ currentTime }) => { - // Remove duplicates - for (let i = 0; i < (watchTime ?? []).length; i++) { - if (watchTime?.[i]?.episodeNumber != episodeNumber && watchTime?.[i]?.mediaId === media.id) { - watchTime?.splice(i, 1); - } - } - - for (let i = 0; i < (watchTime ?? []).length; i++) { - if (watchTime?.[i]?.episodeNumber === episodeNumber && watchTime?.[i]?.mediaId === media.id) { - currentWatchTime = i; - } - } - - if (currentWatchTime === undefined) { - const newWatchTime = { - currentTime, - episodeNumber, - mediaId: media.id, - coverImage: media.coverImage ?? "", - title: media.title, - duration: playerRef.current?.style.getPropertyValue("--media-duration") ?? 0, - watchId, - providerId: provider, - subDub - } as WatchTime; - - currentWatchTime = watchTime?.length; - - // Move it to the front - watchTime?.unshift(newWatchTime); - } else { - if (currentTime != 0) { - // Move to the front - const temp = watchTime[currentWatchTime]; - watchTime?.splice(currentWatchTime, 1); - temp ? watchTime?.unshift(temp) : null; - - Object.assign(watchTime?.[currentWatchTime] ?? {}, { currentTime }); - Object.assign(watchTime?.[currentWatchTime] ?? {}, { duration: playerRef.current?.style.getPropertyValue("--media-duration") ?? 0 }); - } else { - // Move to the front - const temp = watchTime[currentWatchTime]; - watchTime?.splice(currentWatchTime, 1); - temp ? watchTime?.unshift(temp) : null; - - Object.assign(watchTime?.[currentWatchTime] ?? {}, { currentTime }); - } - } - - useWatchTime.setState({ currentTime: watchTime }); - - if (autoSkip) { - const opStart = sources.intro?.start ?? 0; - const opEnd = sources.intro?.end ?? 0; - - const epStart = sources.outro?.start ?? 0; - const epEnd = sources.outro?.end ?? 0; - - if (currentTime > opStart && currentTime < opEnd) { - console.log("Skipping OP..."); - Object.assign(playerRef.current ?? {}, { currentTime: opEnd }); - return null; - } - if (currentTime > epStart && currentTime < epEnd) { - console.log("Skipping EP..."); - Object.assign(playerRef.current ?? {}, { currentTime: epEnd }); - return null; - } - } - - if (Math.round(currentTime) != 0 && Math.round(Number(playerRef.current?.style.getPropertyValue("--media-duration") ?? 0)) != 0) { - if (Math.round(currentTime) === Math.round(Number(playerRef.current?.style.getPropertyValue("--media-duration") ?? 0))) { - goNext(); - } - } - }); - - function goNext() { - const providerEpisodes = episodes.find(providerEps => providerEps.providerId === provider); - - if (providerEpisodes) { - const currentIndex = providerEpisodes.episodes.findIndex(episode => episode.id === watchId); - const nextEpisodeId = providerEpisodes.episodes[currentIndex + 1]?.id ?? ""; - - if (autoNext && nextEpisodeId) { - const nextUrl = `/watch/${media.id}/${provider}/${encodeURIComponent(nextEpisodeId)}/${subDub}`; - window.location.href = nextUrl; - } - } - } - }) - - function changeQuality(value: string) { - const time = playerRef.current?.currentTime ?? 0; - setSrc(value ?? ""); - - setTimeout(() => { - Object.assign(playerRef.current ?? {}, { currentTime: time }); - - void playerRef.current?.play().catch(() => { - // - }); - }) - } - - function changeSub(value?: string) { - const tracks = playerRef.current?.textTracks.toArray(); - - const index = tracks?.filter((x) => x.kind === "subtitles").findIndex((x) => x.src === value); - - playerRef.current?.textTracks.toArray()[index ?? 0]?.setMode("showing"); - } - - function disableSubs(value: boolean) { - useSubtitles.setState({ subtitles: value }); - - if (value) { - const tracks = playerRef.current?.textTracks.toArray(); - - tracks?.forEach((track) => { - if (track.kind === "subtitles") { - track.mode = value ? "disabled" : "showing"; - } - }) - } else { - const tracks = playerRef.current?.textTracks.toArray(); - - tracks?.forEach((track) => { - if (track.kind === "subtitles" && track.label?.toLowerCase() === "english") { - track.mode = "showing"; - } else if (track.kind === "subtitles") { - track.mode = "disabled"; - } - }) - } - } - - function changeSpeed(value: number) { - Object.assign(playerRef.current ?? {}, { playbackRate: value }); - useSpeed.setState({ speed: value }); - } - - const changeAutoNext = (value?: boolean) => { - useAutoNext.setState({ autoNext: value ?? false }) - }; - - const changeAutoFullscreen = (value?: boolean) => { - useAutoFullscreen.setState({ autoFullscreen: value ?? false }) - }; - - const changeAutoSkip = (value?: boolean) => { - useAutoSkip.setState({ autoSkip: value ?? false }) - }; - - function updateFontColor(value?: string) { - // - } - - function updateBackground(value?: string) { - // - } - - function updateFontSize(value?: string) { - const captions = document.querySelector("." + String(styles.captions)); - - if (captions instanceof HTMLElement) { - captions.style.setProperty("--cue-font-size", `calc(var(--overlay-height) / 100 * ${value ?? ""})`); - } - } - - function updateCueMt(_value?: string) { - // - } - - function updateCueMb(_value?: string) { - // - } - - function addCues() { - const introStart = sources.intro.start ?? 0; - const introEnd = sources.intro.end ?? 1; - const outroStart = sources.outro.start ?? 0; - const outroEnd = sources.outro.end ?? 0; - - let useIntro = true; - let useOutro = true; - - if (introEnd <= introStart) { - useIntro = false; - } - - if (outroEnd <= outroStart) { - useOutro = false; - } - - const array = []; - - if (useIntro) { - array.push({ - start: introStart, - end: introEnd, - name: "Intro" - }) - } - - if (useOutro) { - array.push({ - start: outroStart, - end: outroEnd, - name: "Outro" - }) - } - - const webVTTChapters = convertToWebVTT(array); - - const cues = getBase64Chapters(webVTTChapters); - - const track = new TextTrack({ - kind: "chapters", - src: cues, - }); - - //playerRef?.current?.textTracks.add(track); - - /* - playerRef?.current?.textTracks.toArray().forEach((track) => { - if (track.kind === "chapters") { - track.mode = "showing"; - } - }) - */ - - function getBase64Chapters(chapters: string) { - const encoder = new TextEncoder(); - const chaptersData = encoder.encode(chapters); - const base64Chapters = base64ArrayBuffer(chaptersData.buffer); - return `data:text/vtt;base64,${base64Chapters}`; - } - - function base64ArrayBuffer(buffer: ArrayBuffer): string { - let binary = ''; - const bytes = new Uint8Array(buffer); - const len = bytes.byteLength; - - for (let i = 0; i < len; i++) { - binary += String.fromCharCode(bytes[i] ?? 0); - } - - return btoa(binary); - } - - function convertToWebVTT(data: { start: number, end: number, name: string }[]): string { - let webVTT = "WEBVTT\n\n"; - - for (let i = 0; i < data.length; i++) { - const entry = data[i]; - const start = formatTime(entry?.start ?? 0); - const end = formatTime(entry?.end ?? 0); - - webVTT += `${start} --> ${end}\n`; - webVTT += `${entry?.name ?? ""}\n`; - webVTT += "\n"; - } - - return webVTT; - } - - function formatTime(time: number | string): string { - const seconds = Number(time); - const hours = Math.floor(seconds / 3600); - const minutes = Math.floor((seconds % 3600) / 60); - const remainingSeconds = seconds % 60; - - const formattedHours = padZero(Math.floor(hours)); - const formattedMinutes = padZero(Math.floor(minutes)); - const formattedSeconds = padZero(Math.floor(remainingSeconds)); - - return `${formattedHours}:${formattedMinutes}:${formattedSeconds}.000`; - } - - function padZero(value: number): string { - return value.toString().padStart(2, '0'); - } - } - - return ( - <> - - {"Episode " + String(episodeNumber) + " - " + (media.title.english ?? media.title.romaji ?? media.title.native ?? "")} - - - - - - - - - - - - - - - - -
    - { - return { - id: sub.lang, - label: sub.label ?? sub.lang, - kind: "subtitles", - src: sub.url, - language: sub.lang, - default: sub.label ? (sub.label?.toLowerCase() === "english" || sub.label?.toLowerCase() === "en-us") : (sub.lang?.toLowerCase() === "english" || sub.lang?.toLowerCase() === "en-us"), - } - })} - thumbnails={thumbnails} - > - - - -
    - -
    -
    { - if ((event.target as HTMLElement)?.className?.includes?.("media-controls")) { - if (playerRef.current?.paused) { - void playerRef.current?.play(); - } else { - void playerRef.current?.pause(); - } - } - }}> -
    -
    -
    - - - -
    -
    {media.title.english ?? media.title.romaji ?? media.title.native}
    -
    -
    { - setOpen(!open); - setShowChapters(false); - }}> - - - -
    -
    { - setShowChapters(!showChapters); - setOpen(false); - }} className="bg-[hsla(0,0%,76%,0)] rounded-sm p-[5px] w-[32px] h-[32px] flex justify-center items-center ml-auto mr-[12px] cursor-pointer hover:bg-[hsla(0,0%,76%,.2)] transition-all duration-200"> - - - - - -
    - - Speed
    ", - iconID: "speedIcon", - open: "speed", - }, - { - html: "
    Quality
    ", - iconID: "qualIcon", - open: "quality", - }, - { - html: "
    Subtitles
    ", - iconID: "sourceIcon", - open: "subtitle", - }, - { - html: "
    Settings
    ", - iconID: "configIcon", - open: "config", - }, - ], - }, - { - id: "speed", - selectableScene: true, - heading: { - html: "
    Speed
    ", - open: "speed", - hideSubArrow: true, - }, - items: [ - { - html: `
    0.1x
    `, - callback: () => changeSpeed(0.1), - highlightable: true, - selected: speed === 0.1 ? true : false, - }, - { - html: `
    0.5x
    `, - callback: () => changeSpeed(0.5), - highlightable: true, - selected: speed === 0.5 ? true : false, - }, - { - html: `
    1x
    `, - callback: () => changeSpeed(1), - highlightable: true, - selected: speed === 1 ? true : false, - }, - { - html: `
    1.5x
    `, - callback: () => changeSpeed(1.5), - highlightable: true, - selected: speed === 1.5 ? true : false, - }, - { - html: `
    2x
    `, - callback: () => changeSpeed(2), - highlightable: true, - selected: speed === 2 ? true : false, - }, - ], - }, - { - id: "quality", - selectableScene: true, - heading: { - html: "
    Quality
    ", - open: "quality", - hideSubArrow: true, - }, - items: sources && sources.sources[0] ? sources.sources.map((ep) => { - return { - html: `
    ${ - ep.quality - }

    ${ - ep.quality == "1080p" - ? "HD" - : ep.quality == "720p" - ? "SD" - : "" - }

    `, - altText: ep.quality, - callback: () => changeQuality(ep.url), - highlightable: true, - selected: ep.url === src, - }; - }) : [], - }, - { - id: "subtitle", - selectableScene: true, - heading: { - text: "
    Subtitles
    ", - }, - items: subtitles.map((sub) => { - if (!sub.open) { - return { - text: sub.text, - callback: () => changeSub(sub.url), - highlightable: true, - selected: sub.text == "English" ? true : false, - }; - } else { - return { - text: "Styling", - iconID: "fillIcon", - open: "subStyle", - } - } - }), - }, - { - id: "subStyle", - selectableScene: true, - heading: { - text: "
    Subtitle Styling
    ", - }, - items: [ - { - text: "Disable Subs", - toggle: true, - toggleOn: () => disableSubs(true), - toggleOff: () => disableSubs(false), - }, - { - text: "Font Color", - textBox: true, - value: "TBD", - customId: "fontColor", - onInput: function (value: any) { - updateFontColor(value.target.value); - }, - }, - { - text: "Bg. Color", - textBox: true, - value: "TBD", - customId: "bgColor", - onInput: function (value: any) { - updateBackground(value.target.value); - }, - }, - { - text: "Font Size", - textBox: true, - value: "3.5", - customId: "fontSize", - onInput: function (value: any) { - updateFontSize(value.target.value); - }, - }, - { - text: "Margin Top", - textBox: true, - value: "TBD", - customId: "marginTop", - onInput: function (value: any) { - updateCueMt(value.target.value); - }, - }, - { - text: "Margin Bottom", - textBox: true, - value: "TBD", - customId: "marginBottom", - onInput: function (value:any) { - updateCueMb(value.target.value); - }, - }, - ], - }, - { - id: "fillmode", - heading: { - text: "
    Fill Mode
    ", - }, - items: [ - { - text: "Normal", - highlightable: true, - selected: true, - }, - { - text: "Stretch", - highlightable: true, - }, - { - text: "Subtitles", - highlightable: true, - }, - { - text: "Fill", - open: "quality", - // "highlightable": true - }, - ], - }, - - { - id: "config", - heading: { - text: "
    Settings
    ", - back: true, - }, - items: [ - { - html: '

    Auto-Next

    ', - customId: "autoNext", - toggle: true, - toggleOn: () => changeAutoNext(true), - toggleOff: () => changeAutoNext(false), - on: autoNext ? true : false - }, - { - html: '

    Auto-Fullscreen

    ', - customId: "autoFullscreen", - toggle: true, - toggleOn: () => changeAutoFullscreen(true), - toggleOff: () => changeAutoFullscreen(false), - on: autoFullscreen ? true : false - }, - { - html: '

    Auto-Skip

    ', - customId: "autoSkip", - toggle: true, - toggleOn: () => changeAutoSkip(true), - toggleOff: () => changeAutoSkip(false), - on: autoSkip ? true : false - }, - ], - }, - ] - } - /> - -
    -
    -
    -
    -
    -
    -
    - - - - - - - - - - - - Play - Pause - - -
    -
    - - - - - - Unmute - Mute - - - -
    -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - - -
    -
    -
    -
    -
    - / -
    -
    - - - Fullscreen - Exit Fullscreen - - -
    -
    -
    -
    - -
    - - ); -}; - -export const getServerSideProps: GetServerSideProps = async (context) => { - const id: string | string[] | undefined = context.params?.id; - let provider: string | string[] | undefined = context.params?.provider; - const watchId: string | string[] | undefined = context.params?.watchId; - const subDub: string | string[] | undefined = context.params?.subDub; - - if (!Array.isArray(provider) && provider?.toLowerCase().includes("dub")) { - provider = "gogoanime"; - } - - if (!id || !provider || !watchId || !subDub) return { notFound: true }; - - let episodeNumber = -1; - - const media = (await axios.get(String(env.BACKEND_URL) + "/info/" + String(id) + "?apikey=" + String(env.API_KEY))).data as Anime; - const content = (await axios.get(String(env.BACKEND_URL) + "/episodes/" + String(id) + "?apikey=" + String(env.API_KEY))).data as EpisodeData[]; - const episodeCovers = await (await axios.get(`${env.BACKEND_URL}/episode-covers?id=${String(id)}&apikey=${env.API_KEY}`)).data as { episode: number, img: string }[]; - - for (let i = 0; i < content.length; i++) { - const episodes = (content)[i]?.episodes ?? []; - for (let j = 0; j < episodes.length; j++) { - const episodeNumber = (episodes[j]?.number ?? 0); - for (let k = 0; k < episodeCovers.length; k++) { - if (episodeCovers[k]?.episode === episodeNumber) { - if (!episodes[j]?.img) { - Object.assign((content)[i]?.episodes[j] ?? {}, { img: episodeCovers[k]?.img }); - } - break; - } - } - } - } - - const episodeSelector = []; - - for (let i = 0; i < content.length; i++) { - const providerEpisodes = content[i]; - for (let j = 0; j < (providerEpisodes?.episodes ?? []).length; j++) { - const episode = providerEpisodes?.episodes[j]; - if (episode?.id === watchId) { - episodeNumber = episode.number ?? i; - } - - if (providerEpisodes?.providerId.toLowerCase() === (provider as string).toLowerCase()) { - const title = episode?.title; - - if (subDub === "dub") { - if (episode?.hasDub) { - episodeSelector.push({ - title: title ?? "Episode " + String(i + 1), - number: episode.number ?? i + 1, - length: capitalize(providerEpisodes.providerId), - url: `/watch/${id as string}/${provider as string}/${encodeURIComponent(episode.id)}/dub`, - selected: episode?.id === watchId - }) - } - } else { - episodeSelector.push({ - title: title ?? "Episode " + String(i + 1), - number: episode?.number ?? i + 1, - length: capitalize(providerEpisodes.providerId), - url: `/watch/${id as string}/${provider as string}/${encodeURIComponent(episode?.id ?? "")}/sub`, - selected: episode?.id === watchId - }) - } - } - } - } - - const sources = (await axios.post(String(env.BACKEND_URL) + "/sources?apikey=" + String(env.API_KEY), { - id: id, - providerId: provider, - watchId: watchId, - subType: subDub, - episodeNumber: episodeNumber > 0 ? episodeNumber : -1 - }).catch((err) => { - console.error(err); - return { - data: { - sources: [], - subtitles: [], - intro: { - start: 0, - end: 0 - }, - outro: { - start: 0, - end: 0 - } - } - } - })).data as Source; - - for (let i = 0; i < sources?.sources.length; i++) { - if (sources.headers && Object.keys(sources.headers).length > 0) { - //console.log(`${String(env.M3U8_PROXY)}/proxy/m3u8/${encodeURIComponent(String(sources.sources[i]?.url))}/${encodeURIComponent(JSON.stringify(sources.headers))}`); - Object.assign(sources.sources[i] ?? {}, { url: `${String(env.M3U8_PROXY)}/proxy/m3u8/${encodeURIComponent(String(sources.sources[i]?.url))}/${encodeURIComponent(JSON.stringify(sources.headers))}` }) - } - } - - const subtitles = []; - - subtitles.push({ - text: "Styling", - iconID: "fillIcon", - open: "subStyle", - }); - - const languageNames = new Intl.DisplayNames(["en"], { - type: "language", - }); - - let thumbnails = ""; - - sources?.subtitles.map((subtitle) => { - const langCode: string | undefined = subtitle.lang.split("-")[0]; - - let language: string | undefined = "Unknown"; - - if (subtitle.lang?.toLowerCase() === "thumbnails") { - thumbnails = `${String(env.M3U8_PROXY)}/${subtitle.url}`; - return; - } - - try { - language = languageNames.of(langCode ?? ""); - - subtitles.push({ - text: capitalize(language ?? ""), - highlightable: true, - url: subtitle.url, - selected: subtitle.lang == "en-US" ? true : false, - }); - } catch (e) { - // - } - }) - - return { - props: { - media, - episodes: content, - episodeSelector, - episodeNumber, - sources, - subtitles, - provider, - watchId, - thumbnails, - subDub - }, - }; -}; - -export default Watch; - -interface Props { - media: Anime; - episodes: EpisodeData[]; - episodeSelector: { - title: string; - number: number; - length: string; - url: string; - selected: boolean; - }[]; - episodeNumber: number; - sources: Source; - subtitles: { - text: string; - iconID?: string; - open?: string; - url?: string; - selected?: boolean; - highlightable?: boolean; - }[]; - provider: string; - watchId: string; - thumbnails: string; - subDub: string; -} From 5086952fa2326aad40df5fdef46152290ffcc616 Mon Sep 17 00:00:00 2001 From: Eltik Date: Fri, 15 Sep 2023 11:59:38 -0400 Subject: [PATCH 39/77] Update --- anify-frontend/src/components/chapter.tsx | 66 -- .../src/components/chaptersPanel.tsx | 69 -- .../src/components/largeSlideshow.tsx | 65 -- anify-frontend/src/components/mediaItem.tsx | 114 --- anify-frontend/src/components/navbar.tsx | 22 - anify-frontend/src/components/page.tsx | 28 - anify-frontend/src/components/searchItem.tsx | 65 -- .../src/components/settingsPanel.tsx | 657 ------------------ anify-frontend/src/components/slideshow.tsx | 27 - 9 files changed, 1113 deletions(-) delete mode 100644 anify-frontend/src/components/chapter.tsx delete mode 100644 anify-frontend/src/components/chaptersPanel.tsx delete mode 100644 anify-frontend/src/components/largeSlideshow.tsx delete mode 100644 anify-frontend/src/components/mediaItem.tsx delete mode 100644 anify-frontend/src/components/page.tsx delete mode 100644 anify-frontend/src/components/searchItem.tsx delete mode 100644 anify-frontend/src/components/settingsPanel.tsx delete mode 100644 anify-frontend/src/components/slideshow.tsx diff --git a/anify-frontend/src/components/chapter.tsx b/anify-frontend/src/components/chapter.tsx deleted file mode 100644 index 73b678a..0000000 --- a/anify-frontend/src/components/chapter.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* eslint-disable @next/next/no-img-element */ -import moment from "moment"; -import Link from "next/link"; -import { capitalize, truncate } from "~/helper"; -import { type Anime, type Manga, type Episode, type Chapter, MixdropResponse } from "~/types"; - -const Chapter = ({ chapter, media, provider, index, subDub }: { chapter: Episode | Chapter; media: Anime | Manga, provider: string, index: number, subDub: string }) => { - const sendRequest = async (mixdrop: string) => { - const data = await (await fetch(`/api/mixdrop`, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({ - id: mixdrop - }) - })).json() as MixdropResponse; - - const url = data.result[Object.keys(data.result)[0] ?? 0]?.url; - return url; - }; - - if (media.type === "ANIME") { - return ( - -
    -
    - {`${media.title.english -
    -
    -

    {truncate(chapter.title ?? "Episode " + (String(chapter.number ?? index)), 100)}

    -

    - Episode {chapter.number ?? index} · {chapter.updatedAt ? moment(new Date(chapter.updatedAt)).fromNow() : capitalize(provider)} -

    -
    -
    - - ) - } else { - return ( -
    - - -
    -
    {truncate(chapter.title ?? "Chapter " + (String(chapter.number ?? index)), 100)}
    -
    {capitalize(provider)}
    -
    - {(chapter as Chapter).mixdrop ? ( -
    - {/*
    {chapter.number ?? index}
    */} - -
    - ) : null} - -
    - ) - } -}; - -export default Chapter; \ No newline at end of file diff --git a/anify-frontend/src/components/chaptersPanel.tsx b/anify-frontend/src/components/chaptersPanel.tsx deleted file mode 100644 index 6079824..0000000 --- a/anify-frontend/src/components/chaptersPanel.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import Link from "next/link"; -import { useEffect, useRef, useState } from "react"; - -export function ChaptersPanel({ contentSelector, showChapters }: { contentSelector: { title: string, number: number, length: string, url: string, selected: boolean }[], showChapters: boolean }) { - const [selectedChapter, setSelectedChapter] = useState(0); - const [isLoadingMore, setIsLoadingMore] = useState(false); - - const [minChapters, setMinChapters] = useState(0); - const [maxChapters, setMaxChapters] = useState(0); - const ref = useRef(null); - - const amount = 7; - - useEffect(() => { - contentSelector?.forEach((el, i: number) => { - if (el.selected) { - setSelectedChapter(i) - } - }) - - setMinChapters(selectedChapter - amount); - setMaxChapters(selectedChapter + amount > contentSelector.length ? contentSelector.length : selectedChapter + amount); - }, [contentSelector, selectedChapter]) - - const loadMoreChapters = () => { - setIsLoadingMore(true); - - setMinChapters(minChapters - amount < 0 ? 0 : minChapters - amount); - setMaxChapters(maxChapters + amount > contentSelector.length ? contentSelector.length : maxChapters + amount); - - setIsLoadingMore(false); - }; - - return ( -
    -
    - Chapters - - - - - -
    - {contentSelector.map((el, i: number) => { - if (i < minChapters || i >= maxChapters) return null; - return ( - { - setSelectedChapter(i) - }}> -

    {el.number}

    -
    -

    {el.title}

    -

    {el.length}

    -
    - - ) - })} - - -
    - ); -} \ No newline at end of file diff --git a/anify-frontend/src/components/largeSlideshow.tsx b/anify-frontend/src/components/largeSlideshow.tsx deleted file mode 100644 index 22990c2..0000000 --- a/anify-frontend/src/components/largeSlideshow.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/* eslint-disable @next/next/no-img-element */ - -import { Type, type Anime, type Manga } from "~/types"; -import { Swiper, SwiperSlide } from "swiper/react"; - -import "swiper/css"; -import "swiper/css/navigation"; -import "swiper/css/pagination"; -import Image from "next/image"; -import Link from "next/link"; - -const LargeSlideshow = ({ media }: { media: Anime[] | Manga[] }) => { - return ( - <> - - {media.map((media, index: number) => { - return ( - -
    - {/* - {(media as Anime).trailer ? ( -
    -
    -
    -

    c1t4JS7+@8OBKXNNK-s#SV)?qDyeF?_^h%a9z_qH_kN3d3iq zf+W-=K|eD|B8w!(kVG~~Xh=d!5;~I5lY}9b$Wifl@8|i?WkBNZ`IE7BB)?ouahPi8 zdN6+`9=w|G&j69j)xf{6)?~kCv&~c!E|+j)31=jniEw#@GZW52xN(HD5-y)`Hp1Bn z=O7$MI49u>2oP$H=b}42vLHyJ zuoU^G;)E6wHJlH0YSX8ZvJ6I#HYx89GTsqS7PW1K9mK*S(^(h%gmY5`CxhEBQz`~zcZyu ztb*Q03yRPabPwtvxG!DCnTUM9Y?Y-;Syh97v57_tOVQ#}Qqd+s*9O-jjE0?p4uqwa zIZ}YhVECimgnZPUpq8a78E*;XytL z)!@hxTS6{)Dln@Wt6uxM)u03YeXhfjWi2qr3MSw-(M&P;LzZQdvJUw!H)WDvXw1jx zzifKhy&guZJTb11v;_ljBErdEa0Rq>IuajtXEINs9 zlmJaHxe6&wwUj1(rYW_%{+`ZjZadekHBUh2c-! zKHN0w?w0znC`JD~=-gSj3cUrbaSiCtm0Qs9jSb~G=R@~bRkWu^@|x%-6qm`AEP%nj zLLLLoQi>nQFKB_pE9x{z?y)DOAPZq|m2n&f`rM*sdu_D^ydPR~FH>8`?q-FeH?L1cC1AUtc;;^|+zN~C*^eHi?=8_nnq7RBkt#EJ_g(y=lrcQ?L24`l;EKG*{oDRg3rm*C@8JOzA26S{a z(!LCznbiux^R{QDmB)Zt%6YI-sCrA@^v5A`Ezi4esZRr;&E{(K?X_%?TjUAo-)^?z z!MNW~aepu`f^fQJq69%8@>z2Oj67!4;-!S&sRR9tVma)S(7nOjh}>XfQVaSw>=z~T zoiJ!LQJ@hCh(F{Dli<`?u$J{QyD)yp=hZ;eZ=a3fHP+Q~;1|%j$9UoA`{YiSuy#ZD zNn0oGP84)f9zU_k42a-gUf7Nfee(giq+X0)p|F^IX!@UI#6IZlaL(KJuAe?}X(31p znIZS~i@-#oB_!+;H+Kl2ZJGT65~^HDaXM;j7we<$J3OAt7UTKf9^4Sxe&Z_ij61? zH%IAHDPAhK(+PS8j5Q!UVAkVmp)8`?-mQ`k#|L2eM_nmy8gg}OA$T9h#V*)+8UG~4 z`)F3c=kn9g({J1$GjR%r<`vQ0k~ebuOHb3Gu_!Xu08Q=8jnqy<)f&?zj2o<8s=a(e zn}CSP`72CDt(*?H1&(qM+pYADj$5ZltPDZ_X-6&4i(QAok@7GldWBie@eB;LJ1F~d zsmU+Qa;ay*Kb_0RpmThfZt|-Y_dw-&^Oq9PIdC2_<)MeG7}WJ7-jX4{L)uoAN~90B z+u2)V!1@g0Z6MypnAgJ!%=a*Oz-Zq$Je}Ud9aR@oQ#bql|DC$oAE4`;rwF%gRc~Sb zcbslkqp(B0Q$Bt_!r)xSh58O=WDJOYrU2st^S=B9{Rs_!^?aR$zK=W_X^vMhXxQuN z&j4LJGX_3=x-|#04tu^$Lpp&@W$4_jQq~nTPoKAb%Dk=?5XQ``z}p^Xj;d}=u}G)b zD_If^*U@lH#y+0HRw$q|kh2J)hm{MU@;Ay|H{TZC)xf@s)AlP>EDW#6DaN2WH%w>K z|9;B|NtLKn(0{-@1(UyHSE+wqFVK4TOGfH}`MdTirT3co8tHci1onI8V)TASP~M!u zJ@QiK_O@0tLez6dCcZ_O7vvyWICwYXVQ(_^e71y=hJ!m<4=WAb!EEWJXf_eOL~J5r zGZCi|aXJxiC*mDMY$4(dBF-dYD-rJ`;w&Ok%Q-~!5m6wbpNMTlY$sv|5$6(d9uepN E2SwwYDgXcg diff --git a/anify-backend-recode/src/server/impl/chapters.ts b/anify-backend-recode/src/server/impl/chapters.ts index edd1943..afe9508 100644 --- a/anify-backend-recode/src/server/impl/chapters.ts +++ b/anify-backend-recode/src/server/impl/chapters.ts @@ -1,3 +1,4 @@ +import { cacheTime, redis } from ".."; import content from "../../content"; export const handler = async (req: Request): Promise => { @@ -21,7 +22,17 @@ export const handler = async (req: Request): Promise => { }); } + const cached = await redis.get(`chapters:${id}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const data = await content.fetchChapters(String(id)); + + await redis.set(`chapters:${id}`, JSON.stringify(data), "EX", cacheTime); return new Response(JSON.stringify(data), { status: 200, diff --git a/anify-backend-recode/src/server/impl/episodeCovers.ts b/anify-backend-recode/src/server/impl/episodeCovers.ts index fe17415..3ef4f14 100644 --- a/anify-backend-recode/src/server/impl/episodeCovers.ts +++ b/anify-backend-recode/src/server/impl/episodeCovers.ts @@ -1,3 +1,4 @@ +import { cacheTime, redis } from ".."; import { get } from "../../database/impl/modify/get"; import { env } from "../../env"; @@ -54,6 +55,16 @@ export const handler = async (req: Request): Promise => { }); } + const cached = await redis.get(`episode-covers:${id}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + + await redis.set(`episode-covers:${id}`, JSON.stringify(episodeCovers), "EX", cacheTime); + return new Response(JSON.stringify(episodeCovers), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/impl/episodes.ts b/anify-backend-recode/src/server/impl/episodes.ts index a5d7ea5..96ba354 100644 --- a/anify-backend-recode/src/server/impl/episodes.ts +++ b/anify-backend-recode/src/server/impl/episodes.ts @@ -1,3 +1,4 @@ +import { cacheTime, redis } from ".."; import content from "../../content"; export const handler = async (req: Request): Promise => { @@ -21,8 +22,18 @@ export const handler = async (req: Request): Promise => { }); } + const cached = await redis.get(`episodes:${id}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const data = await content.fetchEpisodes(String(id)); + await redis.set(`episodes:${id}`, JSON.stringify(data), "EX", cacheTime); + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/impl/info.ts b/anify-backend-recode/src/server/impl/info.ts index 1e5cbaa..777cf1f 100644 --- a/anify-backend-recode/src/server/impl/info.ts +++ b/anify-backend-recode/src/server/impl/info.ts @@ -1,3 +1,4 @@ +import { cacheTime, redis } from ".."; import { get } from "../../database/impl/modify/get"; export const handler = async (req: Request): Promise => { @@ -21,6 +22,14 @@ export const handler = async (req: Request): Promise => { }); } + const cached = await redis.get(`info:${id}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const data = await get(String(id)); if (!data) { return new Response(JSON.stringify({ error: "No data found." }), { @@ -29,6 +38,8 @@ export const handler = async (req: Request): Promise => { }); } + await redis.set(`info:${id}`, JSON.stringify(data), "EX", cacheTime); + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/impl/pages.ts b/anify-backend-recode/src/server/impl/pages.ts index 7f3184a..57e5937 100644 --- a/anify-backend-recode/src/server/impl/pages.ts +++ b/anify-backend-recode/src/server/impl/pages.ts @@ -1,3 +1,4 @@ +import { cacheTime, redis } from ".."; import content from "../../content"; import { Chapter, Page } from "../../types/types"; import queues from "../../worker"; @@ -47,8 +48,18 @@ export const handler = async (req: Request): Promise => { }); } + const cached = await redis.get(`pages:${chapterTitle}:${chapterNumber}:${providerId}:${readId}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const data = await content.fetchPages(providerId, readId); + await redis.set(`pages:${chapterTitle}:${chapterNumber}:${providerId}:${readId}`, JSON.stringify(data), "EX", cacheTime); + const chapter: Chapter | null = { id: readId, number: chapterNumber, diff --git a/anify-backend-recode/src/server/impl/recent.ts b/anify-backend-recode/src/server/impl/recent.ts index d2528e1..ccb549c 100644 --- a/anify-backend-recode/src/server/impl/recent.ts +++ b/anify-backend-recode/src/server/impl/recent.ts @@ -2,6 +2,7 @@ import queues from "../../worker"; import { search } from "../../database/impl/search/search"; import { Format, Type } from "../../types/enums"; import { recent } from "../../database/impl/misc/recent"; +import { cacheTime, redis } from ".."; export const handler = async (req: Request): Promise => { try { @@ -31,9 +32,19 @@ export const handler = async (req: Request): Promise => { }); } + const cached = await redis.get(`recent:${type}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; const data = await recent((type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, formats, 0, 20); + + await redis.set(`recent:${type}`, JSON.stringify(data), "EX", cacheTime); return new Response(JSON.stringify(data), { status: 200, diff --git a/anify-backend-recode/src/server/impl/relations.ts b/anify-backend-recode/src/server/impl/relations.ts index 70bf5d7..ff4d72d 100644 --- a/anify-backend-recode/src/server/impl/relations.ts +++ b/anify-backend-recode/src/server/impl/relations.ts @@ -1,3 +1,4 @@ +import { cacheTime, redis } from ".."; import { get } from "../../database/impl/modify/get"; import { Anime, Manga } from "../../types/types"; @@ -22,6 +23,14 @@ export const handler = async (req: Request): Promise => { }); } + const cached = await redis.get(`relations:${id}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const data = await get(String(id)); if (!data) { return new Response(JSON.stringify({ error: "No data found." }), { @@ -39,6 +48,8 @@ export const handler = async (req: Request): Promise => { } } + await redis.set(`relations:${id}`, JSON.stringify(relations), "EX", cacheTime); + return new Response(JSON.stringify(relations), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/impl/search.ts b/anify-backend-recode/src/server/impl/search.ts index 0d7666e..be16acb 100644 --- a/anify-backend-recode/src/server/impl/search.ts +++ b/anify-backend-recode/src/server/impl/search.ts @@ -1,6 +1,7 @@ import queues from "../../worker"; import { search } from "../../database/impl/search/search"; import { Format, Type } from "../../types/enums"; +import { cacheTime, redis } from ".."; export const handler = async (req: Request): Promise => { try { @@ -38,18 +39,23 @@ export const handler = async (req: Request): Promise => { }); } + const cached = await redis.get(`search:${type}:${query}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; const data = await search(query, (type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, formats, 0, 20); if (data.length === 0) { queues.searchQueue.add({ type: (type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, query: query, formats: formats }); - - return new Response(JSON.stringify([]), { - status: 200, - headers: { "Content-Type": "application/json" }, - }); } + await redis.set(`search:${type}:${query}`, JSON.stringify(data), "EX", cacheTime); + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/impl/searchAdvanced.ts b/anify-backend-recode/src/server/impl/searchAdvanced.ts index 3ef2f54..388c358 100644 --- a/anify-backend-recode/src/server/impl/searchAdvanced.ts +++ b/anify-backend-recode/src/server/impl/searchAdvanced.ts @@ -1,6 +1,7 @@ import queues from "../../worker"; import { Format, Genres, Type } from "../../types/enums"; import { searchAdvanced } from "../../database/impl/search/searchAdvanced"; +import { cacheTime, redis } from ".."; export const handler = async (req: Request): Promise => { try { @@ -39,18 +40,23 @@ export const handler = async (req: Request): Promise => { const page = Number(body?.page ?? url.searchParams.get("page") ?? "1"); const perPage = Number(body?.perPage ?? url.searchParams.get("perPage") ?? "20"); + const cached = await redis.get(`search-advanced:${type}:${query}:${genres}:${genresExcluded}:${tags}:${tagsExcluded}:${year}:${page}:${perPage}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; const data = await searchAdvanced(query, (type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, formats, page, perPage, genres as Genres[], genresExcluded as Genres[], year, tags, tagsExcluded); if (data.length === 0) { queues.searchQueue.add({ type: (type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, query: query, formats: formats, genres: genres as Genres[], genresExcluded: genresExcluded as Genres[], year: year, tags: tags, tagsExcluded: tagsExcluded }); - - return new Response(JSON.stringify([]), { - status: 200, - headers: { "Content-Type": "application/json" }, - }); } + await redis.set(`search-advanced:${type}:${query}:${genres}:${genresExcluded}:${tags}:${tagsExcluded}:${year}:${page}:${perPage}`, JSON.stringify(data), "EX", cacheTime); + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/impl/seasonal.ts b/anify-backend-recode/src/server/impl/seasonal.ts index dc20e62..4a2d4ff 100644 --- a/anify-backend-recode/src/server/impl/seasonal.ts +++ b/anify-backend-recode/src/server/impl/seasonal.ts @@ -1,6 +1,7 @@ import { Format, Type } from "../../types/enums"; import { loadSeasonal } from "../../lib/impl/seasonal"; import { seasonal } from "../../database/impl/misc/seasonal"; +import { cacheTime, redis } from ".."; export const handler = async (req: Request): Promise => { try { @@ -41,11 +42,21 @@ export const handler = async (req: Request): Promise => { fields = fieldsArray.filter(Boolean); } + const cached = await redis.get(`seasonal:${type}:${fields.join(",")}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; const seasonData = await loadSeasonal({ type: (type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, formats }); const data = await seasonal(seasonData?.trending ?? [], seasonData?.popular ?? [], seasonData?.top ?? [], seasonData?.seasonal ?? [], fields); + await redis.set(`seasonal:${type}:${fields.join(",")}`, JSON.stringify(data), "EX", cacheTime); + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/impl/sources.ts b/anify-backend-recode/src/server/impl/sources.ts index 36c48fc..4051a72 100644 --- a/anify-backend-recode/src/server/impl/sources.ts +++ b/anify-backend-recode/src/server/impl/sources.ts @@ -1,3 +1,4 @@ +import { cacheTime, redis } from ".."; import content from "../../content"; import { StreamingServers, SubType } from "../../types/enums"; import queues from "../../worker"; @@ -62,6 +63,14 @@ export const handler = async (req: Request): Promise => { const server = body.server ?? paths[6] ?? url.searchParams.get("server") ?? undefined ? (decodeURIComponent(body.server ?? paths[6] ?? url.searchParams.get("server") ?? undefined) as StreamingServers) : undefined; + const cached = await redis.get(`sources:${id}:${episodeNumber}:${providerId}:${watchId}:${subType}:${server}`); + if (cached) { + return new Response(cached, { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const data = await content.fetchSources(providerId, watchId, subType as SubType, server as StreamingServers); if (!data) @@ -72,6 +81,8 @@ export const handler = async (req: Request): Promise => { if (data) queues.skipTimes.add({ id, episode: episodeNumber, toInsert: data }); + await redis.set(`sources:${id}:${episodeNumber}:${providerId}:${watchId}:${subType}:${server}`, JSON.stringify(data), "EX", cacheTime); + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/impl/stats.ts b/anify-backend-recode/src/server/impl/stats.ts index 6f90be7..47a21b0 100644 --- a/anify-backend-recode/src/server/impl/stats.ts +++ b/anify-backend-recode/src/server/impl/stats.ts @@ -1,3 +1,4 @@ +import { cacheTime, redis } from ".."; import { stats } from "../../database/impl/misc/stats"; import { get } from "../../database/impl/modify/get"; @@ -7,6 +8,14 @@ export const handler = async (req: Request): Promise => { const paths = url.pathname.split("/"); paths.shift(); + const cached = await redis.get(`stats`); + if (cached) { + return new Response(JSON.stringify(cached), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + const data = await stats(); if (!data) { return new Response(JSON.stringify({ error: "No data found." }), { @@ -15,6 +24,8 @@ export const handler = async (req: Request): Promise => { }); } + await redis.set(`stats`, JSON.stringify(data), "EX", cacheTime); + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" }, diff --git a/anify-backend-recode/src/server/index.ts b/anify-backend-recode/src/server/index.ts index 0c6ae4c..1888326 100644 --- a/anify-backend-recode/src/server/index.ts +++ b/anify-backend-recode/src/server/index.ts @@ -7,11 +7,18 @@ import colors from "colors"; import { env } from "../env"; -export const start = async () => { - const redis = new Redis((env.REDIS_URL as string) || "redis://localhost:6379"); - const cacheTime = env.REDIS_CACHE_TIME; - const whitelist = env.API_KEY_WHITELIST; +export const redis: Redis = env.REDIS_URL ? new Redis((env.REDIS_URL as string) || "redis://localhost:6379") : { + get: async () => null, + set: (): Promise<"OK"> => Promise.resolve("OK"), + on: () => Redis.prototype, + keys: async () => [], + connect: async () => void 0, + call: async () => void 0, +} as any; + +export const cacheTime = env.REDIS_CACHE_TIME || 60 * 60 * 24 * 7 * 2; +export const start = async () => { const routes: { [key: string]: { path: string; handler: (req: Request) => Promise } } = {}; const routeFiles = readdirSync(join(import.meta.dir, "./impl")); for (const file of routeFiles) { From 740aa4745ba48ece982bdcea73c8b6ff948cbd34 Mon Sep 17 00:00:00 2001 From: Eltik Date: Tue, 12 Sep 2023 09:10:37 -0400 Subject: [PATCH 29/77] PDFs workin! --- anify-backend-recode/.gitignore | 2 + anify-backend-recode/db.sqlite | Bin 5808128 -> 5808128 bytes anify-backend-recode/src/index.ts | 18 ++- anify-backend-recode/src/lib/impl/pdf.ts | 145 +++++++++++++++++- .../src/server/impl/chapters.ts | 2 +- anify-backend-recode/src/server/impl/pages.ts | 14 +- .../src/server/impl/recent.ts | 2 +- anify-backend-recode/src/server/index.ts | 18 ++- anify-backend-recode/src/types/types.ts | 28 ++++ anify-backend-recode/src/worker/impl/pdf.ts | 2 +- 10 files changed, 203 insertions(+), 28 deletions(-) diff --git a/anify-backend-recode/.gitignore b/anify-backend-recode/.gitignore index f81d56e..9910413 100644 --- a/anify-backend-recode/.gitignore +++ b/anify-backend-recode/.gitignore @@ -167,3 +167,5 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.\* + +/manga \ No newline at end of file diff --git a/anify-backend-recode/db.sqlite b/anify-backend-recode/db.sqlite index 39d7e1c39a0026849e91a0221df4ee52ce29c1db..33e12d7f24b7bfe1fd90292dc9c9ce37d1e76770 100644 GIT binary patch delta 3216 zcmcJRTWl298OL{h!G>VRCM^aGW!Ta{%AWPy=L{v-=4Qu)iy_7ZWW<>>XS^Hl&g{M ziI>Xyt=8v!_wPTeIeYg{b!UNBI$J(TBpSb;NF=@oeEI5TE&0jR$?NNzaqB}ksBgKt zoU`j%A5NFr?AH2*{~V^33M?p`=M=EHG0+vM$1h zB~fG$Dj=pwmcTS-N)kSC!S1_c_a%WkpdM%d8i6IZ?7pU-Y+jQ1S0d4nxU{_31T+In zfn~rGz;d7kXa$}G+JJUo1@IK`HQ?*ON}vN+1*`_v0G+^EU>)!cU_HPA8-Nt>O<*JN zE#PTj6R;V02KY9x1xN!3$N*ipmKXUi4lHefIVD?05-q{t8_65fXWKqqQrCP81~%O| z@$*$DHVz#hZdrf6`vUX5_AAdN5_Ma)bab{Snw!tJ48AqkRCj5({c%QDsCZdttb)qS z_E-)fWU`{mJdc^EKt^*kM{Gn~nk|=$-qx#pP0DEXo6hl(GneyI5&_CwtdxBB6C{BWBeKI@0uZ-(6sZ9{)P_p86X{o2E8SMR_7 z%Lli9kxHlb)n?1RFf-f#IUKNjaPiv1bGIJezVhI;H@Lsw{^|Y8lYjZZfAFKppu4ZW zb0v5G`qW=9zWm_zi(h4U=Th+5^&vT^ULV>s!G*8fI~#rwPIBQ#;hpf^a5B6Rei*(N z-iE(B;dFS1gM&NahxabS;S?OcA6utJUMy}aZtu0q%;h{*BrYlE>`~5godUPp&3S3= zP{m{wkF!WV?{PW1>~Q5Q<6u?gtj9T4{LN((o|kj%4A;-NvP(`eFa^Uy&P&WTm^+%D z@$ndSY?Gt8^6A(y4s+1W*)&%q`Ps7_#LF_5*k$l=prBZIoaMM&Hs^7L9Atsw3J$os zY3>-abLDIX6z5G8!K=(3RavRN1LGr*WF2Sz=R21?4l_^teiqt4=uXOyDXM1OZ@|AOA3akLrgQ`?-hkYX8j>_FGG z6?o8?4OO3V@)c-%_SA86qdA*EMhCW;j<=knGt!9HMq<4b2zY^cERby#Z_^|FKO8a*Ng&WTs!M!<|lcu7TOc$;1VL#`4mxftu0XkGdZj3F`c8r+4jtsai97^KN(NQgtSsD2c(n z6ZI>DCl4o|2>$ScffXAiSujj2s>sk3iew^Fq+1$%6Lmurbj46GjyH+0Cg_-#^ab0Z zn!qr{1WAgBk*vxDVMWGBS0pBB*pd}ph*yoUs$;Aw(D8gFSP~|>g%Pid5|Vk1M?_#U zQglO7sip|juwp5Ix2ns6EQs^Hb*7l2%tT}wJVUZ%>WDC^B8}*bCYxaFX|05v`k(w5EXSELcqw0DJV$Q6b;Ivyr{ESiHm#d1WF^Ofv~JW0pNiM z&ud77!Rv(Sx+JoA@iOGbs;Ke{#6wL?co;2Gi2}JbW+7~-8j5u$X(quuHEObng}i78 znaP4qVck@wpc4ygh+qQ-X;9T9CMAYo)k4HNp9`@-HmZoRshASN0)`%VY9XjwLy{(& zsw7(qFVR|v_%YDc*-jS35KL1y6$Wpk0)aAki$W*VK&B;IvTjj`H5(&-N*0enHITZh zsi1bl0Qq7a8CVvP!I(%?s#9LpYIVd9(b~B>W@I=rJ~H03A^O?xmOWc)%pVV~eK)zW zkv|r{nvwB+gME+l#?%GN)HDofRYB3=HJdjPfe|8&8X^T5OKR}y>ZL1#yT_90;LXd) zr~YplCg1B_=SSUs)Z<6Jeze1ncKXpSKicg_d;F-+kNW-SIX@ckqrHCgydUlJqy2t# cz>g04(V!n4@}t9k^nxD^`O%TLqT$JZ19c-O6#xJL delta 479 zcmWm8%Ssz@9L4dOWRi(?9LLtwRAao?cxjsH#dxW4wAFZP?M+P^TzWs_wX!qy-7i)Al8y+XFc3pL^h@TS zY+Pq1+EKBNO(f8UcHD!7yUs=@9CYD69-tdZJVXytc!XZ`A&q`yFn~b}VHhJA#TXuA z99c|Y5>uGQ6XftTw2t%FI|g^{F#mU4?79~eH|yTFR8vV_iL2z9lIKcZD0!)5MoB@* ztdcn;^GX(!yi&5Lq { - await start(); + //await start(); + const chapter = { + id: "/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1", + title: "Chapter 1", + number: 1, + updatedAt: 1660688888000, + }; + + const pages = await mangaProviders.mangasee.fetchPages("/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1"); + + await loadPDF({ id: "dc481ed5-4925-4f3c-bac1-e73f1e7ed338", providerId: "mangasee", chapter, pages: pages ?? [] }).then(console.log); }); async function before() { diff --git a/anify-backend-recode/src/lib/impl/pdf.ts b/anify-backend-recode/src/lib/impl/pdf.ts index 1bcfb70..8384c0a 100644 --- a/anify-backend-recode/src/lib/impl/pdf.ts +++ b/anify-backend-recode/src/lib/impl/pdf.ts @@ -1,4 +1,4 @@ -import { Chapter, Page } from "../../types/types"; +import { Chapter, Manga, Page, UploadStatus } from "../../types/types"; import { wait } from "../../helper"; import PDFDocument from "pdfkit"; @@ -10,23 +10,125 @@ import { promisify } from "node:util"; import imageSize from "image-size"; import { env } from "../../env"; import emitter, { Events } from ".."; +import { get } from "../../database/impl/modify/get"; +import { update } from "../../database/impl/modify/update"; -export const loadPDF = async (data: { providerId: string; chapter: Chapter; pages: string | Page[] }): Promise => { +export const loadPDF = async (data: { id: string; providerId: string; chapter: Chapter; pages: string | Page[] }) => { const useMixdrop = env.USE_MIXDROP; if (!useMixdrop) return; - if (typeof data.pages === "string") { - return await createNovelPDF(data.providerId, data.chapter, data.pages); + const mixdropEmail = env.MIXDROP_EMAIL; + const mixdropKey = env.MIXDROP_KEY; + + if (!mixdropEmail || !mixdropKey) return; + + const manga = await get(data.id); + if (!manga) return await emitter.emitAsync(Events.COMPLETED_PAGES_UPLOAD, ""); + + const chapters = (manga as Manga).chapters; + const mixdrop = chapters.data.find((x) => x.providerId === data.providerId)?.chapters.find((x) => x.id === data.chapter.id)?.mixdrop; + + // Check if the file is removed + const isRemoved = await checkIsDeleted(mixdropEmail ?? "", mixdropKey ?? "", mixdrop ?? ""); + if (!isRemoved && mixdrop != undefined) return mixdrop; + + const pdfPath = typeof data.pages === "string" ? await createNovelPDF(data.providerId, data.chapter, data.pages) : await createMangaPDF(data.providerId, data.chapter, data.pages); + const file = Bun.file(pdfPath); + if (!file.exists()) return await emitter.emitAsync(Events.COMPLETED_PAGES_UPLOAD, ""); + + const form = new FormData(); + form.append("email", mixdropEmail); + form.append("key", mixdropKey); + form.append("file", file, `${data.chapter.title.replace(/[^\w .-]/gi, "")}.pdf`); + + const result = await ( + await fetch("https://ul.mixdrop.co/api", { + method: "POST", + body: form, + }) + ).json(); + + if (result.success) { + for (const chap of chapters.data) { + if (chap.providerId === data.providerId) { + const chaps = chap.chapters; + for (const ch of chaps) { + if (ch.id === data.chapter.id) { + ch.mixdrop = result[0]; + } + } + } + } + + Object.assign(manga, { chapters }); + await update(manga); + + const maxThreshold = 100; + let threshold = 0; + + const interval = setInterval(async () => { + const isComplete = await checkRemoteStatus(result.result?.fileref); + const key = Object.keys(isComplete.result)[0]; + + if (isComplete.result[key].status === "OK") { + console.log(colors.green("Completed uploading ") + colors.blue(data.chapter.title) + colors.green(" to Mixdrop")); + try { + unlinkSync(pdfPath); + // Try to delete parent folders + const parentFolder = pdfPath.split("/").slice(0, -1).join("/"); + if (readdirSync(parentFolder).length === 0) { + unlinkSync(parentFolder); + const parentParentFolder = parentFolder.split("/").slice(0, -1).join("/"); + if (readdirSync(parentParentFolder).length === 0) { + unlinkSync(parentParentFolder); + } + } + } catch (e) { + // + } + + clearInterval(interval); + return; + } else { + if (threshold >= maxThreshold + 5) { + console.error(colors.red("ERROR: ") + colors.blue(`Mixdrop upload for ${data.chapter.title} is taking too long.`)); + try { + unlinkSync(pdfPath); + // Try to delete parent folders + const parentFolder = pdfPath.split("/").slice(0, -1).join("/"); + if (readdirSync(parentFolder).length === 0) { + unlinkSync(parentFolder); + const parentParentFolder = parentFolder.split("/").slice(0, -1).join("/"); + if (readdirSync(parentParentFolder).length === 0) { + unlinkSync(parentParentFolder); + } + } + } catch (e) { + // + } + + clearInterval(interval); + return; + } + threshold++; + } + }, 1000); + + await emitter.emitAsync(Events.COMPLETED_PAGES_UPLOAD, result.result?.fileref); + return pdfPath; + } else { + console.error(colors.red("Failed to upload PDF to Mixdrop.")); + return await emitter.emitAsync(Events.COMPLETED_PAGES_UPLOAD, ""); } - return await createMangaPDF(data.providerId, data.chapter, data.pages); }; export const createNovelPDF = async (providerId: string, chapter: Chapter, pages: string): Promise => { - await emitter.emitAsync(Events.COMPLETED_PAGES_UPLOAD, ""); return ""; }; export const createMangaPDF = async (providerId: string, chapter: Chapter, pages: Page[]): Promise => { + if (chapter.title.length === 0) Object.assign(chapter, { title: `Chapter ${chapter.number}` }); + const parentFolder = `./manga/${providerId}/${chapter.title.replace(/[^\w .-]/gi, "")}`; const chapterTitle = chapter.title.replace(/[^\w .-]/gi, ""); @@ -125,7 +227,6 @@ export const createMangaPDF = async (providerId: string, chapter: Chapter, pages } } - await emitter.emitAsync(Events.COMPLETED_PAGES_UPLOAD, `${parentFolder}/${chapter.title.replace(/[^\w .-]/gi, "")}.pdf`); return `${parentFolder}/${chapter.title.replace(/[^\w .-]/gi, "")}.pdf`; }; @@ -136,7 +237,6 @@ export const createMangaPDF = async (providerId: string, chapter: Chapter, pages * @param headers (Optional) Headers to be included in the HTTP request. * @returns A Promise that resolves when the download is complete. */ - async function downloadFile(url: string, outputPath: string, headers?: Record): Promise { try { const response = await fetch(url, { headers }); @@ -184,3 +284,32 @@ async function getImageSize(path: string): Promise<{ width: number; height: numb return null; } } + +const checkRemoteStatus = async (mixdrop: string): Promise => { + const mixdropEmail = env.MIXDROP_EMAIL; + const mixdropKey = env.MIXDROP_KEY; + + const res: UploadStatus = await (await fetch(`https://api.mixdrop.co/fileinfo2?email=${mixdropEmail}&key=${mixdropKey}&ref[]=${mixdrop}`)).json(); + return res; +}; + +const checkIsDeleted = async (email: string, key: string, fileRef: string): Promise => { + let pages = 1; + const initial = await (await fetch(`https://api.mixdrop.co/removed?email=${email}&key=${key}&page=1`)).json(); + if (!Array.isArray(initial.result)) return false; + + for (const file of initial.result) { + if (file.fileref === fileRef) return true; + } + + pages = initial.pages; + + for (let i = 2; i <= pages; i++) { + const initial = await (await fetch(`https://api.mixdrop.co/removed?email=${email}&key=${key}&page=${i}`)).json(); + for (const file of initial.result) { + if (file.fileref === fileRef) return true; + } + } + + return false; +}; diff --git a/anify-backend-recode/src/server/impl/chapters.ts b/anify-backend-recode/src/server/impl/chapters.ts index afe9508..b5969c0 100644 --- a/anify-backend-recode/src/server/impl/chapters.ts +++ b/anify-backend-recode/src/server/impl/chapters.ts @@ -31,7 +31,7 @@ export const handler = async (req: Request): Promise => { } const data = await content.fetchChapters(String(id)); - + await redis.set(`chapters:${id}`, JSON.stringify(data), "EX", cacheTime); return new Response(JSON.stringify(data), { diff --git a/anify-backend-recode/src/server/impl/pages.ts b/anify-backend-recode/src/server/impl/pages.ts index 57e5937..2072b7f 100644 --- a/anify-backend-recode/src/server/impl/pages.ts +++ b/anify-backend-recode/src/server/impl/pages.ts @@ -16,9 +16,9 @@ export const handler = async (req: Request): Promise => { }) : null; - const chapterTitle = body.chapterTitle ?? paths[1] ?? url.searchParams.get("chapterTitle") ?? null; - if (!chapterTitle) { - return new Response(JSON.stringify({ error: "No chapter title provided." }), { + const id = body.id ?? paths[1] ?? url.searchParams.get("id") ?? null; + if (!id) { + return new Response(JSON.stringify({ error: "No media ID provided." }), { status: 400, headers: { "Content-Type": "application/json" }, }); @@ -48,7 +48,7 @@ export const handler = async (req: Request): Promise => { }); } - const cached = await redis.get(`pages:${chapterTitle}:${chapterNumber}:${providerId}:${readId}`); + const cached = await redis.get(`pages:${id}:${chapterNumber}:${providerId}:${readId}`); if (cached) { return new Response(cached, { status: 200, @@ -58,15 +58,15 @@ export const handler = async (req: Request): Promise => { const data = await content.fetchPages(providerId, readId); - await redis.set(`pages:${chapterTitle}:${chapterNumber}:${providerId}:${readId}`, JSON.stringify(data), "EX", cacheTime); + await redis.set(`pages:${id}:${chapterNumber}:${providerId}:${readId}`, JSON.stringify(data), "EX", cacheTime); const chapter: Chapter | null = { id: readId, number: chapterNumber, - title: chapterTitle, + title: "", }; - if (chapter) await queues.uploadPages.add({ providerId, chapter, pages: (data as Page[] | string) ?? [] }); + if (chapter) await queues.uploadPages.add({ id, providerId, chapter, pages: (data as Page[] | string) ?? [] }); return new Response(JSON.stringify(data), { status: 200, diff --git a/anify-backend-recode/src/server/impl/recent.ts b/anify-backend-recode/src/server/impl/recent.ts index ccb549c..f81272f 100644 --- a/anify-backend-recode/src/server/impl/recent.ts +++ b/anify-backend-recode/src/server/impl/recent.ts @@ -43,7 +43,7 @@ export const handler = async (req: Request): Promise => { const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; const data = await recent((type.toUpperCase() === "NOVEL" ? Type.MANGA : type.toUpperCase()) as Type, formats, 0, 20); - + await redis.set(`recent:${type}`, JSON.stringify(data), "EX", cacheTime); return new Response(JSON.stringify(data), { diff --git a/anify-backend-recode/src/server/index.ts b/anify-backend-recode/src/server/index.ts index 1888326..c51afb0 100644 --- a/anify-backend-recode/src/server/index.ts +++ b/anify-backend-recode/src/server/index.ts @@ -7,14 +7,16 @@ import colors from "colors"; import { env } from "../env"; -export const redis: Redis = env.REDIS_URL ? new Redis((env.REDIS_URL as string) || "redis://localhost:6379") : { - get: async () => null, - set: (): Promise<"OK"> => Promise.resolve("OK"), - on: () => Redis.prototype, - keys: async () => [], - connect: async () => void 0, - call: async () => void 0, -} as any; +export const redis: Redis = env.REDIS_URL + ? new Redis((env.REDIS_URL as string) || "redis://localhost:6379") + : ({ + get: async () => null, + set: (): Promise<"OK"> => Promise.resolve("OK"), + on: () => Redis.prototype, + keys: async () => [], + connect: async () => void 0, + call: async () => void 0, + } as any); export const cacheTime = env.REDIS_CACHE_TIME || 60 * 60 * 24 * 7 * 2; diff --git a/anify-backend-recode/src/types/types.ts b/anify-backend-recode/src/types/types.ts index 32cabd4..6d8aa5f 100644 --- a/anify-backend-recode/src/types/types.ts +++ b/anify-backend-recode/src/types/types.ts @@ -208,3 +208,31 @@ export type SkipTime = { }; export type Time = Pick["episodes"][number]; + +/** + * @description MixDrop upload status + */ +export type UploadStatus = { + success: true; + result: ResultData; +}; + +type ResultData = { + [key: string]: FileData; +}; + +type FileData = { + fileref: string; + title: string; + size: string; + duration: null; + subtitle: boolean; + isvideo: boolean; + isaudio: boolean; + added: string; + status: string; + deleted: boolean; + thumb: null; + url: string; + yourfile: boolean; +}; diff --git a/anify-backend-recode/src/worker/impl/pdf.ts b/anify-backend-recode/src/worker/impl/pdf.ts index 4fa0e84..e8b68de 100644 --- a/anify-backend-recode/src/worker/impl/pdf.ts +++ b/anify-backend-recode/src/worker/impl/pdf.ts @@ -3,7 +3,7 @@ import QueueExecutor from "../../lib/executor"; import { Chapter, Page } from "../../types/types"; import { loadPDF } from "../../lib/impl/pdf"; -const executor = new QueueExecutor<{ providerId: string; chapter: Chapter; pages: string | Page[] }>("page-upload-executor") +const executor = new QueueExecutor<{ id: string; providerId: string; chapter: Chapter; pages: string | Page[] }>("page-upload-executor") .executor(async (data) => { const media = await loadPDF(data); return media; From fbfd4aab96772ceb9391f8d98b6b070919a4eeb5 Mon Sep 17 00:00:00 2001 From: Eltik Date: Tue, 12 Sep 2023 09:16:24 -0400 Subject: [PATCH 30/77] Merged backend recode to main folder --- anify-backend-recode/.eslintignore | 2 - anify-backend-recode/.eslintrc | 33 - anify-backend-recode/.gitignore | 171 - anify-backend-recode/.prettierignore | 12 - anify-backend-recode/.prettierrc.json | 13 - anify-backend-recode/README.md | 15 - anify-backend-recode/package-lock.json | 43 - anify-backend-recode/package.json | 36 - anify-backend-recode/src/content/index.ts | 11 - anify-backend-recode/src/database/index.ts | 94 - anify-backend-recode/src/env.ts | 17 - anify-backend-recode/src/helper/extractor.ts | 567 - anify-backend-recode/src/helper/index.ts | 45 - .../src/helper/stringSimilarity.ts | 159 - anify-backend-recode/src/helper/title.ts | 121 - anify-backend-recode/src/index.ts | 94 - anify-backend-recode/src/server/index.ts | 54 - anify-backend-recode/src/worker/index.ts | 15 - anify-backend-recode/tsconfig.json | 22 - anify-backend/.env.example | 37 +- anify-backend/.gitignore | 197 +- anify-backend/README.md | 196 +- .../db.sqlite | Bin anify-backend/package-lock.json | 4764 +-- anify-backend/package.json | 85 +- anify-backend/pnpm-lock.yaml | 5819 --- anify-backend/prisma/schema.prisma | 146 - .../src/content/impl/chapters.ts | 0 .../src/content/impl/chapters/index.ts | 120 - .../src/content/impl/episodes.ts | 0 .../content/impl/episodes/episodeCovers.ts | 43 - .../src/content/impl/episodes/index.ts | 117 - .../src/content/impl/pages.ts | 0 anify-backend/src/content/impl/pages/index.ts | 38 - .../src/content/impl/schedule/index.ts | 74 - .../src/content/impl/sources.ts | 0 .../src/content/impl/sources/index.ts | 20 - anify-backend/src/content/index.ts | 2 +- anify-backend/src/crawl.ts | 159 - .../src/database/impl/misc/recent.ts | 0 .../src/database/impl/misc/seasonal.ts | 0 .../src/database/impl/misc/stats.ts | 0 .../src/database/impl/modify/create.ts | 0 .../src/database/impl/modify/delete.ts | 0 .../src/database/impl/modify/get.ts | 0 .../src/database/impl/modify/update.ts | 0 .../src/database/impl/search/search.ts | 0 .../database/impl/search/searchAdvanced.ts | 0 .../impl/skipTimes/createSkipTimes.ts | 0 .../database/impl/skipTimes/getSkipTimes.ts | 0 .../impl/skipTimes/updateSkipTimes.ts | 0 anify-backend/src/database/index.ts | 514 +- anify-backend/src/database/postgresql.ts | 661 - anify-backend/src/env.ts | 6 - anify-backend/src/helper/event.ts | 14 - anify-backend/src/helper/executor.ts | 31 - anify-backend/src/helper/extractor.ts | 488 +- anify-backend/src/helper/generator/index.ts | 114 - anify-backend/src/helper/index.ts | 142 +- .../src/helper/proxies/goodProxies.json | 6105 ---- anify-backend/src/helper/proxies/index.ts | 383 - anify-backend/src/helper/proxies/info.d.ts | 339 - anify-backend/src/helper/proxies/proxies.json | 29946 ---------------- anify-backend/src/helper/queue.ts | 163 - .../src/helper/request.ts | 0 anify-backend/src/helper/stringSimilarity.ts | 24 +- anify-backend/src/helper/title.ts | 100 +- anify-backend/src/index.ts | 138 +- anify-backend/src/keys/index.ts | 118 - anify-backend/src/lib/entry.ts | 45 - .../src/lib/executor.ts | 0 .../src/lib/impl/entry.ts | 2 +- .../src/lib/impl/mappings.ts | 0 .../src/lib/impl/pdf.ts | 0 .../src/lib/impl/search.ts | 0 .../src/lib/impl/seasonal.ts | 0 .../src/lib/impl/skipTimes.ts | 0 .../src/lib/index.ts | 0 anify-backend/src/lib/mappings.ts | 437 - anify-backend/src/lib/search.ts | 19 - anify-backend/src/lib/season.ts | 11 - anify-backend/src/lib/skipTimes.ts | 146 - anify-backend/src/lib/upload.ts | 312 - .../src/mapping/impl/anime/animeflix.ts | 150 - .../src/mapping/impl/anime/animepahe.ts | 170 - .../src/mapping/impl/anime/gogoanime.ts | 130 - anify-backend/src/mapping/impl/anime/index.ts | 92 - anify-backend/src/mapping/impl/anime/kass.ts | 320 - .../src/mapping/impl/anime/nineanime.ts | 348 - anify-backend/src/mapping/impl/anime/zoro.ts | 162 - .../src/mapping/impl/information/anilist.ts | 1297 - .../src/mapping/impl/information/comicK.ts | 152 - .../src/mapping/impl/information/index.ts | 46 - .../src/mapping/impl/information/kitsu.ts | 160 - .../src/mapping/impl/information/mal.ts | 97 - .../src/mapping/impl/information/simkl.ts | 199 - .../src/mapping/impl/information/tvdb.ts | 191 - .../src/mapping/impl/manga/comicK.ts | 184 - anify-backend/src/mapping/impl/manga/index.ts | 60 - .../src/mapping/impl/manga/jnovels.ts | 95 - .../src/mapping/impl/manga/mangadex.ts | 178 - .../src/mapping/impl/manga/mangafox.ts | 97 - .../src/mapping/impl/manga/mangasee.ts | 127 - .../src/mapping/impl/manga/novelbuddy.ts | 70 - .../src/mapping/impl/manga/novelupdates.ts | 119 - .../src/mapping/impl/manga/readlightnovels.ts | 104 - .../src/mapping/impl/manga/vynovel.ts | 66 - anify-backend/src/mapping/impl/meta/index.ts | 20 - .../src/mapping/impl/meta/kitsuanime.ts | 241 - .../src/mapping/impl/meta/kitsumanga.ts | 241 - anify-backend/src/mapping/impl/meta/simkl.ts | 65 - anify-backend/src/mapping/impl/meta/tmdb.ts | 133 - anify-backend/src/mapping/impl/meta/tvdb.ts | 195 - anify-backend/src/mapping/impl/request.ts | 83 - anify-backend/src/mapping/index.ts | 296 - .../src/mappings/impl/anime/animepahe.ts | 0 .../src/mappings/impl/anime/gogoanime.ts | 0 .../src/mappings/impl/anime/index.ts | 0 .../src/mappings/impl/anime/nineanime.ts | 0 .../src/mappings/impl/anime/zoro.ts | 0 .../src/mappings/impl/base/anilist.ts | 0 .../src/mappings/impl/base/index.ts | 0 .../src/mappings/impl/base/mangadex.ts | 0 .../src/mappings/impl/information/anilist.ts | 0 .../src/mappings/impl/information/comick.ts | 0 .../src/mappings/impl/information/index.ts | 0 .../src/mappings/impl/information/kitsu.ts | 0 .../src/mappings/impl/information/mal.ts | 0 .../src/mappings/impl/information/mangadex.ts | 0 .../src/mappings/impl/information/tvdb.ts | 0 .../src/mappings/impl/manga/comick.ts | 0 .../src/mappings/impl/manga/index.ts | 0 .../src/mappings/impl/manga/jnovels.ts | 0 .../src/mappings/impl/manga/mangadex.ts | 0 .../src/mappings/impl/manga/mangasee.ts | 0 .../src/mappings/impl/manga/novelupdates.ts | 0 .../src/mappings/impl/meta/anilist.ts | 0 .../src/mappings/impl/meta/index.ts | 0 .../src/mappings/impl/meta/kitsu.ts | 0 .../src/mappings/impl/meta/mal.ts | 0 .../src/mappings/impl/meta/tmdb.ts | 0 .../src/mappings/impl/meta/tvdb.ts | 0 .../src/mappings/index.ts | 0 .../src/proxies/executor.ts | 0 .../src/proxies/impl/checkProxies.ts | 0 .../src/proxies/impl/fetchProxies.ts | 0 .../src/proxies/impl/scrapeProxies.ts | 0 .../src/proxies/index.ts | 0 anify-backend/src/scripts/buildDb.ts | 22 - anify-backend/src/scripts/checkEnv.ts | 31 - anify-backend/src/scripts/checkProxies.ts | 6 - anify-backend/src/scripts/clear.ts | 17 - anify-backend/src/scripts/createKey.ts | 9 - anify-backend/src/scripts/export.ts | 65 - anify-backend/src/scripts/flushSafe.ts | 6 - anify-backend/src/scripts/import.ts | 121 - anify-backend/src/scripts/scrapeProxies.ts | 6 - .../src/server/impl/chapters.ts | 0 .../src/server/impl/episodeCovers.ts | 0 .../src/server/impl/episodes.ts | 0 .../src/server/impl/info.ts | 0 .../src/server/impl/pages.ts | 0 .../src/server/impl/recent.ts | 0 .../src/server/impl/relations.ts | 0 .../src/server/impl/search.ts | 0 .../src/server/impl/searchAdvanced.ts | 0 .../src/server/impl/seasonal.ts | 0 .../src/server/impl/sources.ts | 0 .../src/server/impl/stats.ts | 0 anify-backend/src/server/index.ts | 2039 +- anify-backend/src/tasks/index.ts | 131 - .../src/types/enums.ts | 0 .../src/types/types.ts | 0 anify-backend/src/worker/entry.ts | 14 - .../src/worker/impl/entry.ts | 0 .../src/worker/impl/mappings.ts | 0 .../src/worker/impl/pdf.ts | 0 .../src/worker/impl/search.ts | 0 .../src/worker/impl/seasonal.ts | 0 .../src/worker/impl/skipTimes.ts | 0 anify-backend/src/worker/index.ts | 14 +- anify-backend/src/worker/mapping.ts | 14 - anify-backend/src/worker/search.ts | 14 - anify-backend/src/worker/season.ts | 14 - anify-backend/src/worker/skipTimes.ts | 14 - anify-backend/src/worker/upload.ts | 14 - anify-backend/tsconfig.json | 34 +- anify-backend/yarn.lock | 2670 -- .../pages/read/[id]/[provider]/[readId].tsx | 4 +- 189 files changed, 619 insertions(+), 64127 deletions(-) delete mode 100644 anify-backend-recode/.eslintignore delete mode 100644 anify-backend-recode/.eslintrc delete mode 100644 anify-backend-recode/.gitignore delete mode 100644 anify-backend-recode/.prettierignore delete mode 100644 anify-backend-recode/.prettierrc.json delete mode 100644 anify-backend-recode/README.md delete mode 100644 anify-backend-recode/package-lock.json delete mode 100644 anify-backend-recode/package.json delete mode 100644 anify-backend-recode/src/content/index.ts delete mode 100644 anify-backend-recode/src/database/index.ts delete mode 100644 anify-backend-recode/src/env.ts delete mode 100644 anify-backend-recode/src/helper/extractor.ts delete mode 100644 anify-backend-recode/src/helper/index.ts delete mode 100644 anify-backend-recode/src/helper/stringSimilarity.ts delete mode 100644 anify-backend-recode/src/helper/title.ts delete mode 100644 anify-backend-recode/src/index.ts delete mode 100644 anify-backend-recode/src/server/index.ts delete mode 100644 anify-backend-recode/src/worker/index.ts delete mode 100644 anify-backend-recode/tsconfig.json rename {anify-backend-recode => anify-backend}/db.sqlite (100%) delete mode 100644 anify-backend/pnpm-lock.yaml delete mode 100644 anify-backend/prisma/schema.prisma rename {anify-backend-recode => anify-backend}/src/content/impl/chapters.ts (100%) delete mode 100644 anify-backend/src/content/impl/chapters/index.ts rename {anify-backend-recode => anify-backend}/src/content/impl/episodes.ts (100%) delete mode 100644 anify-backend/src/content/impl/episodes/episodeCovers.ts delete mode 100644 anify-backend/src/content/impl/episodes/index.ts rename {anify-backend-recode => anify-backend}/src/content/impl/pages.ts (100%) delete mode 100644 anify-backend/src/content/impl/pages/index.ts delete mode 100644 anify-backend/src/content/impl/schedule/index.ts rename {anify-backend-recode => anify-backend}/src/content/impl/sources.ts (100%) delete mode 100644 anify-backend/src/content/impl/sources/index.ts delete mode 100644 anify-backend/src/crawl.ts rename {anify-backend-recode => anify-backend}/src/database/impl/misc/recent.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/misc/seasonal.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/misc/stats.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/modify/create.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/modify/delete.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/modify/get.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/modify/update.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/search/search.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/search/searchAdvanced.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/skipTimes/createSkipTimes.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/skipTimes/getSkipTimes.ts (100%) rename {anify-backend-recode => anify-backend}/src/database/impl/skipTimes/updateSkipTimes.ts (100%) delete mode 100644 anify-backend/src/database/postgresql.ts delete mode 100644 anify-backend/src/helper/event.ts delete mode 100644 anify-backend/src/helper/executor.ts delete mode 100644 anify-backend/src/helper/generator/index.ts delete mode 100644 anify-backend/src/helper/proxies/goodProxies.json delete mode 100644 anify-backend/src/helper/proxies/index.ts delete mode 100644 anify-backend/src/helper/proxies/info.d.ts delete mode 100644 anify-backend/src/helper/proxies/proxies.json delete mode 100644 anify-backend/src/helper/queue.ts rename {anify-backend-recode => anify-backend}/src/helper/request.ts (100%) delete mode 100644 anify-backend/src/keys/index.ts delete mode 100644 anify-backend/src/lib/entry.ts rename {anify-backend-recode => anify-backend}/src/lib/executor.ts (100%) rename {anify-backend-recode => anify-backend}/src/lib/impl/entry.ts (95%) rename {anify-backend-recode => anify-backend}/src/lib/impl/mappings.ts (100%) rename {anify-backend-recode => anify-backend}/src/lib/impl/pdf.ts (100%) rename {anify-backend-recode => anify-backend}/src/lib/impl/search.ts (100%) rename {anify-backend-recode => anify-backend}/src/lib/impl/seasonal.ts (100%) rename {anify-backend-recode => anify-backend}/src/lib/impl/skipTimes.ts (100%) rename {anify-backend-recode => anify-backend}/src/lib/index.ts (100%) delete mode 100644 anify-backend/src/lib/mappings.ts delete mode 100644 anify-backend/src/lib/search.ts delete mode 100644 anify-backend/src/lib/season.ts delete mode 100644 anify-backend/src/lib/skipTimes.ts delete mode 100644 anify-backend/src/lib/upload.ts delete mode 100644 anify-backend/src/mapping/impl/anime/animeflix.ts delete mode 100644 anify-backend/src/mapping/impl/anime/animepahe.ts delete mode 100644 anify-backend/src/mapping/impl/anime/gogoanime.ts delete mode 100644 anify-backend/src/mapping/impl/anime/index.ts delete mode 100644 anify-backend/src/mapping/impl/anime/kass.ts delete mode 100644 anify-backend/src/mapping/impl/anime/nineanime.ts delete mode 100644 anify-backend/src/mapping/impl/anime/zoro.ts delete mode 100644 anify-backend/src/mapping/impl/information/anilist.ts delete mode 100644 anify-backend/src/mapping/impl/information/comicK.ts delete mode 100644 anify-backend/src/mapping/impl/information/index.ts delete mode 100644 anify-backend/src/mapping/impl/information/kitsu.ts delete mode 100644 anify-backend/src/mapping/impl/information/mal.ts delete mode 100644 anify-backend/src/mapping/impl/information/simkl.ts delete mode 100644 anify-backend/src/mapping/impl/information/tvdb.ts delete mode 100644 anify-backend/src/mapping/impl/manga/comicK.ts delete mode 100644 anify-backend/src/mapping/impl/manga/index.ts delete mode 100644 anify-backend/src/mapping/impl/manga/jnovels.ts delete mode 100644 anify-backend/src/mapping/impl/manga/mangadex.ts delete mode 100644 anify-backend/src/mapping/impl/manga/mangafox.ts delete mode 100644 anify-backend/src/mapping/impl/manga/mangasee.ts delete mode 100644 anify-backend/src/mapping/impl/manga/novelbuddy.ts delete mode 100644 anify-backend/src/mapping/impl/manga/novelupdates.ts delete mode 100644 anify-backend/src/mapping/impl/manga/readlightnovels.ts delete mode 100644 anify-backend/src/mapping/impl/manga/vynovel.ts delete mode 100644 anify-backend/src/mapping/impl/meta/index.ts delete mode 100644 anify-backend/src/mapping/impl/meta/kitsuanime.ts delete mode 100644 anify-backend/src/mapping/impl/meta/kitsumanga.ts delete mode 100644 anify-backend/src/mapping/impl/meta/simkl.ts delete mode 100644 anify-backend/src/mapping/impl/meta/tmdb.ts delete mode 100644 anify-backend/src/mapping/impl/meta/tvdb.ts delete mode 100644 anify-backend/src/mapping/impl/request.ts delete mode 100644 anify-backend/src/mapping/index.ts rename {anify-backend-recode => anify-backend}/src/mappings/impl/anime/animepahe.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/anime/gogoanime.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/anime/index.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/anime/nineanime.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/anime/zoro.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/base/anilist.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/base/index.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/base/mangadex.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/information/anilist.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/information/comick.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/information/index.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/information/kitsu.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/information/mal.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/information/mangadex.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/information/tvdb.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/manga/comick.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/manga/index.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/manga/jnovels.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/manga/mangadex.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/manga/mangasee.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/manga/novelupdates.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/meta/anilist.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/meta/index.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/meta/kitsu.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/meta/mal.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/meta/tmdb.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/impl/meta/tvdb.ts (100%) rename {anify-backend-recode => anify-backend}/src/mappings/index.ts (100%) rename {anify-backend-recode => anify-backend}/src/proxies/executor.ts (100%) rename {anify-backend-recode => anify-backend}/src/proxies/impl/checkProxies.ts (100%) rename {anify-backend-recode => anify-backend}/src/proxies/impl/fetchProxies.ts (100%) rename {anify-backend-recode => anify-backend}/src/proxies/impl/scrapeProxies.ts (100%) rename {anify-backend-recode => anify-backend}/src/proxies/index.ts (100%) delete mode 100644 anify-backend/src/scripts/buildDb.ts delete mode 100644 anify-backend/src/scripts/checkEnv.ts delete mode 100644 anify-backend/src/scripts/checkProxies.ts delete mode 100644 anify-backend/src/scripts/clear.ts delete mode 100644 anify-backend/src/scripts/createKey.ts delete mode 100644 anify-backend/src/scripts/export.ts delete mode 100644 anify-backend/src/scripts/flushSafe.ts delete mode 100644 anify-backend/src/scripts/import.ts delete mode 100644 anify-backend/src/scripts/scrapeProxies.ts rename {anify-backend-recode => anify-backend}/src/server/impl/chapters.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/episodeCovers.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/episodes.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/info.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/pages.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/recent.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/relations.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/search.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/searchAdvanced.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/seasonal.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/sources.ts (100%) rename {anify-backend-recode => anify-backend}/src/server/impl/stats.ts (100%) delete mode 100644 anify-backend/src/tasks/index.ts rename {anify-backend-recode => anify-backend}/src/types/enums.ts (100%) rename {anify-backend-recode => anify-backend}/src/types/types.ts (100%) delete mode 100644 anify-backend/src/worker/entry.ts rename {anify-backend-recode => anify-backend}/src/worker/impl/entry.ts (100%) rename {anify-backend-recode => anify-backend}/src/worker/impl/mappings.ts (100%) rename {anify-backend-recode => anify-backend}/src/worker/impl/pdf.ts (100%) rename {anify-backend-recode => anify-backend}/src/worker/impl/search.ts (100%) rename {anify-backend-recode => anify-backend}/src/worker/impl/seasonal.ts (100%) rename {anify-backend-recode => anify-backend}/src/worker/impl/skipTimes.ts (100%) delete mode 100644 anify-backend/src/worker/mapping.ts delete mode 100644 anify-backend/src/worker/search.ts delete mode 100644 anify-backend/src/worker/season.ts delete mode 100644 anify-backend/src/worker/skipTimes.ts delete mode 100644 anify-backend/src/worker/upload.ts delete mode 100644 anify-backend/yarn.lock diff --git a/anify-backend-recode/.eslintignore b/anify-backend-recode/.eslintignore deleted file mode 100644 index 7d671e7..0000000 --- a/anify-backend-recode/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -/dist -**/*.js \ No newline at end of file diff --git a/anify-backend-recode/.eslintrc b/anify-backend-recode/.eslintrc deleted file mode 100644 index 13b5ac5..0000000 --- a/anify-backend-recode/.eslintrc +++ /dev/null @@ -1,33 +0,0 @@ -{ - "parser": "@typescript-eslint/parser", - "plugins": [ - "@typescript-eslint" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "rules": { - "@typescript-eslint/ban-types": "warn", - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-empty-function": "off", - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-namespace": "off", - "@typescript-eslint/no-loss-of-precision": "off", - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-non-null-asserted-optional-chain": "off", - "@typescript-eslint/no-unnecessary-type-constraint": "warn", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/no-var-requires": "warn", - "no-console": "off", - "no-empty": "warn", - "no-prototype-builtins": "off", - "no-redeclare": "warn", - "no-useless-escape": "off", - "no-async-promise-executor": "off", - "prefer-const": "warn", - "array-bracket-spacing": ["error", "never"] - } -} \ No newline at end of file diff --git a/anify-backend-recode/.gitignore b/anify-backend-recode/.gitignore deleted file mode 100644 index 9910413..0000000 --- a/anify-backend-recode/.gitignore +++ /dev/null @@ -1,171 +0,0 @@ -# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore - -# Logs - -logs -_.log -npm-debug.log_ -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) - -report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json - -# Runtime data - -pids -_.pid -_.seed -\*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover - -lib-cov - -# Coverage directory used by tools like istanbul - -coverage -\*.lcov - -# nyc test coverage - -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) - -.grunt - -# Bower dependency directory (https://bower.io/) - -bower_components - -# node-waf configuration - -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) - -build/Release - -# Dependency directories - -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) - -web_modules/ - -# TypeScript cache - -\*.tsbuildinfo - -# Optional npm cache directory - -.npm - -# Optional eslint cache - -.eslintcache - -# Optional stylelint cache - -.stylelintcache - -# Microbundle cache - -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history - -.node_repl_history - -# Output of 'npm pack' - -\*.tgz - -# Yarn Integrity file - -.yarn-integrity - -# dotenv environment variable files - -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) - -.cache -.parcel-cache - -# Next.js build output - -.next -out - -# Nuxt.js build / generate output - -.nuxt -dist - -# Gatsby files - -.cache/ - -# Comment in the public line in if your project uses Gatsby and not Next.js - -# https://nextjs.org/blog/next-9-1#public-directory-support - -# public - -# vuepress build output - -.vuepress/dist - -# vuepress v2.x temp and cache directory - -.temp -.cache - -# Docusaurus cache and generated files - -.docusaurus - -# Serverless directories - -.serverless/ - -# FuseBox cache - -.fusebox/ - -# DynamoDB Local files - -.dynamodb/ - -# TernJS port file - -.tern-port - -# Stores VSCode versions used for testing VSCode extensions - -.vscode-test - -# yarn v2 - -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.\* - -/manga \ No newline at end of file diff --git a/anify-backend-recode/.prettierignore b/anify-backend-recode/.prettierignore deleted file mode 100644 index eeda442..0000000 --- a/anify-backend-recode/.prettierignore +++ /dev/null @@ -1,12 +0,0 @@ -node_modules -*.js -*.d.ts -*.md -*.json -*.lock -*.yml -*.yaml -Dockerfile -Dockerfile.* -.eslintrc -*.html \ No newline at end of file diff --git a/anify-backend-recode/.prettierrc.json b/anify-backend-recode/.prettierrc.json deleted file mode 100644 index 0e41e21..0000000 --- a/anify-backend-recode/.prettierrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "useTabs": false, - "tabWidth": 4, - "semi": true, - "singleQuote": false, - "bracketSpacing": true, - "bracketSameLine": false, - "arrowParens": "always", - "parser": "typescript", - "printWidth": 10000, - "proseWrap": "never", - "endOfLine": "lf" -} diff --git a/anify-backend-recode/README.md b/anify-backend-recode/README.md deleted file mode 100644 index 6077abe..0000000 --- a/anify-backend-recode/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# test - -To install dependencies: - -```bash -bun install -``` - -To run: - -```bash -bun run index.ts -``` - -This project was created using `bun init` in bun v0.8.1. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/anify-backend-recode/package-lock.json b/anify-backend-recode/package-lock.json deleted file mode 100644 index 5b6026b..0000000 --- a/anify-backend-recode/package-lock.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "test", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "test", - "dependencies": { - "eventemitter2": "^6.4.9" - }, - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - } - }, - "node_modules/bun-types": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-0.8.1.tgz", - "integrity": "sha512-VuCBox66P/3a8gVOffLCWIS6vdpXq4y3eJuF3VnsyC5HpykmIjkcr5wYDn22qQdeTUmOfCcBy1SZmtrZCeUr3A==", - "dev": true - }, - "node_modules/eventemitter2": { - "version": "6.4.9", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" - }, - "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - } - } -} diff --git a/anify-backend-recode/package.json b/anify-backend-recode/package.json deleted file mode 100644 index 4b6355f..0000000 --- a/anify-backend-recode/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "test", - "module": "index.ts", - "type": "module", - "scripts": { - "start": "bun run dist/index.js", - "dev": "bun run src/index.ts", - "build": "bun build ./src/index.ts --outdir ./dist --target node", - "prettier": "prettier --write .", - "eslint": "eslint --ext .ts src/** --fix", - "lint": "bun run prettier && bun run eslint" - }, - "devDependencies": { - "@types/crypto-js": "^4.1.2", - "@types/pdfkit": "^0.12.10", - "@typescript-eslint/eslint-plugin": "latest", - "@typescript-eslint/parser": "latest", - "bun-types": "latest", - "eslint": "^8.48.0", - "prettier": "^3.0.3" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "dependencies": { - "@extractus/article-extractor": "^8.0.2", - "cheerio": "^1.0.0-rc.12", - "colors": "^1.4.0", - "crypto-js": "^4.1.1", - "dotenv": "^16.3.1", - "eventemitter2": "latest", - "image-size": "^1.0.2", - "ioredis": "^5.3.2", - "pdfkit": "^0.13.0" - } -} diff --git a/anify-backend-recode/src/content/index.ts b/anify-backend-recode/src/content/index.ts deleted file mode 100644 index d8e5344..0000000 --- a/anify-backend-recode/src/content/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { fetchChapters } from "./impl/chapters"; -import { fetchEpisodes } from "./impl/episodes"; -import { fetchSources } from "./impl/sources"; -import { fetchPages } from "./impl/pages"; - -export default { - fetchChapters, - fetchEpisodes, - fetchSources, - fetchPages, -}; diff --git a/anify-backend-recode/src/database/index.ts b/anify-backend-recode/src/database/index.ts deleted file mode 100644 index f393403..0000000 --- a/anify-backend-recode/src/database/index.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Database } from "bun:sqlite"; - -export const db = new Database("db.sqlite"); - -export const init = async () => { - const anime = ` - CREATE TABLE IF NOT EXISTS anime ( - id TEXT PRIMARY KEY, - slug TEXT, - coverImage TEXT, - bannerImage TEXT, - trailer TEXT, - status TEXT, - season TEXT DEFAULT 'UNKNOWN', - title JSON, - currentEpisode INTEGER, - mappings JSON DEFAULT '[]', - synonyms JSON DEFAULT '[]', - countryOfOrigin TEXT, - description TEXT, - duration INTEGER, - color TEXT, - year INTEGER, - rating JSON, - popularity JSON, - type TEXT, - format TEXT DEFAULT 'UNKNOWN', - relations JSON DEFAULT '[]', - totalEpisodes REAL, - genres JSON DEFAULT '[]', - tags JSON DEFAULT '[]', - episodes JSON DEFAULT '{"latest": {"updatedAt": 0, "latestEpisode": 0, "latestTitle": ""}, "data": []}', - averageRating REAL, - averagePopularity REAL, - artwork JSON DEFAULT '[]', - characters JSON DEFAULT '[]' - ); - `; - - const manga = ` - CREATE TABLE IF NOT EXISTS manga ( - id TEXT PRIMARY KEY, - slug TEXT, - coverImage TEXT, - bannerImage TEXT, - status TEXT, - title JSON, - mappings JSON DEFAULT '[]', - synonyms JSON DEFAULT '[]', - countryOfOrigin TEXT, - description TEXT, - duration INTEGER, - color TEXT, - year INTEGER, - rating JSON, - popularity JSON, - type TEXT, - format TEXT DEFAULT 'UNKNOWN', - relations JSON DEFAULT '[]', - currentChapter INTEGER, - totalChapters REAL, - totalVolumes REAL, - genres JSON DEFAULT '[]', - tags JSON DEFAULT '[]', - chapters JSON DEFAULT '{"latest": {"updatedAt": 0, "latestChapter": 0, "latestTitle": ""}, "data": []}', - averageRating REAL, - averagePopularity REAL, - artwork JSON DEFAULT '[]', - characters JSON DEFAULT '[]' - ); - `; - - const skipTimes = ` - CREATE TABLE IF NOT EXISTS skipTimes ( - id TEXT PRIMARY KEY, - episodes JSON DEFAULT '{}' - ); - `; - - const apiKey = ` - CREATE TABLE IF NOT EXISTS apiKey ( - id TEXT PRIMARY KEY, - key TEXT, - requestCount INTEGER DEFAULT 0, - createdAt INTEGER DEFAULT 0, - updatedAt INTEGER DEFAULT 0 - ); - `; - - await db.query(anime).run(); - await db.query(manga).run(); - await db.query(skipTimes).run(); - await db.query(apiKey).run(); -}; diff --git a/anify-backend-recode/src/env.ts b/anify-backend-recode/src/env.ts deleted file mode 100644 index 44447a4..0000000 --- a/anify-backend-recode/src/env.ts +++ /dev/null @@ -1,17 +0,0 @@ -// All environment variables. -export const env = { - PORT: Number(process.env.PORT) || 3000, - NINEANIME_RESOLVER: process.env.NINEANIME_RESOLVER, - NINEANIME_KEY: process.env.NINEANIME_KEY, - REDIS_URL: process.env.REDIS_URL, - REDIS_CACHE_TIME: Number(process.env.REDIS_CACHE_TIME) || 60 * 60 * 24 * 7, - USE_API_KEYS: process.env.USE_API_KEYS || "false", - MASTER_KEY: process.env.MASTER_KEY, - API_KEY_WHITELIST: process.env.API_KEY_WHITELIST?.split(",") || [], - CENSYS_ID: process.env.CENSYS_ID, - CENSYS_SECRET: process.env.CENSYS_SECRET, - SIMKL_CLIENT_ID: process.env.SIMKL_CLIENT_ID, - USE_MIXDROP: process.env.USE_MIXDROP === "true" || false, - MIXDROP_EMAIL: process.env.MIXDROP_EMAIL, - MIXDROP_KEY: process.env.MIXDROP_KEY, -}; diff --git a/anify-backend-recode/src/helper/extractor.ts b/anify-backend-recode/src/helper/extractor.ts deleted file mode 100644 index db96a22..0000000 --- a/anify-backend-recode/src/helper/extractor.ts +++ /dev/null @@ -1,567 +0,0 @@ -import CryptoJS from "crypto-js"; -import { load } from "cheerio"; -import { substringAfter, substringBefore } from "."; -import { env } from "process"; -import { Source } from "../types/types"; -import { StreamingServers } from "../types/enums"; - -export default class Extractor { - private url: string; - private result: Source; - - constructor(url: string, result: Source) { - this.url = url; - this.result = result; - } - - async extract(server: StreamingServers): Promise { - switch (server) { - case StreamingServers.GogoCDN: - return await this.extractGogoCDN(this.url, this.result); - case StreamingServers.StreamSB: - return await this.extractStreamSB(this.url, this.result); - case StreamingServers.VidCloud: - return await this.extractVidCloud(this.url, this.result); - case StreamingServers.VidStreaming: - return await this.extractGogoCDN(this.url, this.result); - case StreamingServers.StreamTape: - return await this.extractStreamTape(this.url, this.result); - case StreamingServers.MyCloud: - return await this.extractMyCloud(this.url, this.result); - case StreamingServers.Filemoon: - return await this.extractFileMoon(this.url, this.result); - case StreamingServers.VizCloud: - return await this.extractVizCloud(this.url, this.result); - case StreamingServers.Kwik: - return await this.extractKwik(this.url, this.result); - case StreamingServers.AllAnime: - return await this.extractAllAnime(this.url, this.result); - case StreamingServers.AnimeFlix: - return await this.extractAnimeFlix(this.url, this.result); - default: - return undefined; - } - } - - public async extractAnimeFlix(url: string, result: Source): Promise { - const data = await ( - await fetch(url, { - headers: { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36", - }, - }) - ).text(); - - const $ = load(data); - // const source = 'https://cdn.discordapp.com/attachments/1126579073980846132/1141026618941382696/1080p-ROCK.m3u8'; - /* - var options = { - video: plyrplayer, - subUrl: JSON.parse('[{"url":"https://proxy.gogocden.site/https://cdn.discordapp.com/attachments/1126579089524932669/1141026620472315946/ENG.ass","title":"ENG","lang":"ENG"}]').find(sub => sub.title === name)?.url, - fonts: ['/public/trebuc.woff2', '/public/AdobeArabic-Bold.woff2'], - workerUrl: '/public/subtitle-worker.js', - legacyWorkerUrl: '/public/subtitle-worker-legacy.js' - }; - */ - - const source = $.html().split("const source = '")[1].split("';")[0]; - if (source.includes("https://cdn.discordapp.com")) { - result.sources.push({ - quality: "1080p", - url: source, - }); - } else { - result.sources.push({ - quality: "auto", - url: source, - }); - - const req = await fetch(source, { - headers: { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36", - Referer: "https://api.animeflix.live", - }, - }); - - const resolutions = (await req.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - resolutions?.forEach((res: string) => { - const index = source.lastIndexOf("/"); - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - const url = source.slice(0, index); - result.sources.push({ - url: url + "/" + res.split("\n")[1], - quality: quality + "p", - }); - }); - } - - try { - const subtitles = JSON.parse($.html().split("instance.setTrackByUrl(JSON.parse(`")[1].split("`).find")[0]); - subtitles.map((subtitle: { title: string; lang: string; url: string }) => { - result.subtitles.push({ - label: subtitle.title, - lang: subtitle.lang, - url: subtitle.url, - }); - }); - } catch (e) { - // - } - - return result; - } - - public async extractMyCloud(url: string, result: Source): Promise { - const proxy = env.NINEANIME_RESOLVER || "https://9anime.resolver.net"; - const proxyKey: string = env.NINEANIME_KEY || `9anime`; - - const lolToken = await (await fetch("https://mcloud.to/futoken")).text(); - - const m3u8Req = await fetch(`${proxy}/rawMcloud?apikey=${proxyKey}`, { - method: "POST", - body: JSON.stringify({ - query: url, - futoken: lolToken, - }), - headers: { - "Content-Type": "application/json", - }, - }); - const data = await m3u8Req.json(); - - const m3u8File = data.rawURL; - - const mainReq = await ( - await fetch(m3u8File, { - headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, - }) - ).json(); - - for (const track of mainReq.result?.tracks ?? []) { - result.subtitles.push({ - url: track.file, - lang: track.label ? track.label : track.kind, - label: track.kind, - }); - } - - const file = mainReq.result?.sources[0]?.file; - - const req = await fetch(file, { - headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, - }); - - const resolutions = (await req.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - resolutions?.forEach((res: string) => { - const index = file.lastIndexOf("/"); - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - const url = file.slice(0, index); - result.sources.push({ - url: url + "/" + res.split("\n")[1], - quality: quality + "p", - }); - }); - - // Master m3u8 file - result.sources.push({ - quality: "auto", - url: file, - }); - - //result.headers = {}; // TEMP doesnt require proxy - - return result; - } - - public async extractFileMoon(url: string, result: Source): Promise { - const proxy = env.NINEANIME_RESOLVER || "https://9anime.resolver.com"; - const proxyKey: string = env.NINEANIME_KEY || `9anime`; - const data = await (await fetch(`https://filemoon.sx/d/${url}`)).text(); - - const resolver = await fetch(`${proxy}/filemoon?apikey=${proxyKey}`, { - method: "POST", - body: JSON.stringify({ - query: data, - }), - }); - - const resolverData = await resolver.json(); - - result.sources.push({ - url: resolverData.url, - quality: "auto", - }); - - const resReq = await fetch(resolverData.url, { headers: { Referer: "https://9anime.pl" } }); - const resolutions = (await resReq.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - - resolutions?.forEach((res: string) => { - const index = resolverData.url.lastIndexOf("/"); - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - const url = resolverData.url.slice(0, index); - - result.sources.push({ - url: url + "/" + res.split("\n")[1], - quality: quality + "p", - }); - }); - - return result; - } - - /** - * @description Requires a VizStream ID. Uses NineAnime resolver. - * @param vidStreamId VizStream ID - * @returns Promise - */ - public async extractVizCloud(url: string, result: Source): Promise { - const proxy = env.NINEANIME_RESOLVER || "https://9anime.resolver.net"; - const proxyKey: string = env.NINEANIME_KEY || `9anime`; - - const lolToken = await (await fetch("https://vidstream.pro/futoken")).text(); - - const m3u8Req = await fetch(`${proxy}/rawVizcloud?apikey=${proxyKey}`, { - method: "POST", - body: JSON.stringify({ - query: url, - futoken: lolToken, - }), - headers: { - "Content-Type": "application/json", - }, - }); - const data = await m3u8Req.json(); - - const m3u8File = data.rawURL; - - const mainReq = await ( - await fetch(m3u8File, { - headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, - }) - ).json(); - - for (const track of mainReq.result?.tracks ?? []) { - result.subtitles.push({ - url: track.file, - lang: track.label ? track.label : track.kind, - label: track.kind, - }); - } - - const file = mainReq.result?.sources[0]?.file; - - const req = await fetch(file, { - headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, - }); - - const resolutions = (await req.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - resolutions?.forEach((res: string) => { - const index = file.lastIndexOf("/"); - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - const url = file.slice(0, index); - result.sources.push({ - url: url + "/" + res.split("\n")[1], - quality: quality + "p", - }); - }); - - // Master m3u8 file - result.sources.push({ - quality: "auto", - url: file, - }); - - //result.headers = {}; // TEMP doesnt require proxy - - return result; - } - - public async extractGogoCDN(url: string, result: Source): Promise { - const keys = { - key: CryptoJS.enc.Utf8.parse("37911490979715163134003223491201"), - secondKey: CryptoJS.enc.Utf8.parse("54674138327930866480207815084989"), - iv: CryptoJS.enc.Utf8.parse("3134003223491201"), - }; - - const req = await fetch(url); - const $ = load(await req.text()); - - const encyptedParams = await generateEncryptedAjaxParams(new URL(url).searchParams.get("id") ?? ""); - - const encryptedData = await fetch(`${new URL(url).protocol}//${new URL(url).hostname}/encrypt-ajax.php?${encyptedParams}`, { - headers: { - "X-Requested-With": "XMLHttpRequest", - }, - }); - - const decryptedData = await decryptAjaxData((await encryptedData.json())?.data); - if (!decryptedData.source) throw new Error("No source found. Try a different server."); - - if (decryptedData.source[0].file.includes(".m3u8")) { - const resResult = await fetch(decryptedData.source[0].file.toString()); - const resolutions = (await resResult.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - - resolutions?.forEach((res: string) => { - const index = decryptedData.source[0].file.lastIndexOf("/"); - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - const url = decryptedData.source[0].file.slice(0, index); - - result.sources.push({ - url: url + "/" + res.split("\n")[1], - quality: quality + "p", - }); - }); - - decryptedData.source.forEach((source: any) => { - result.sources.push({ - url: source.file, - quality: "default", - }); - }); - } else { - decryptedData.source.forEach((source: any) => { - result.sources.push({ - url: source.file, - quality: source.label.split(" ")[0] + "p", - }); - }); - - decryptedData.source_bk.forEach((source: any) => { - result.sources.push({ - url: source.file, - quality: "backup", - }); - }); - } - - return result; - - function generateEncryptedAjaxParams(id: string) { - const encryptedKey = CryptoJS.AES.encrypt(id, keys.key, { - iv: keys.iv, - }); - - const scriptValue = $("script[data-name='episode']").data().value as string; - - const decryptedToken = CryptoJS.AES.decrypt(scriptValue, keys.key, { - iv: keys.iv, - }).toString(CryptoJS.enc.Utf8); - - return `id=${encryptedKey}&alias=${id}&${decryptedToken}`; - } - - function decryptAjaxData(encryptedData: string) { - const decryptedData = CryptoJS.enc.Utf8.stringify( - CryptoJS.AES.decrypt(encryptedData, keys.secondKey, { - iv: keys.iv, - }), - ); - - return JSON.parse(decryptedData); - } - } - - public async extractStreamSB(url: string, result: Source): Promise { - throw new Error("Method not implemented yet."); - } - - public async extractVidCloud(url: string, result: Source): Promise { - const host = "https://megacloud.tv"; - const id = url.split("/").pop()?.split("?")[0]; - - const options = { - headers: { - "X-Requested-With": "XMLHttpRequest", - Referer: url, - }, - }; - - const request = await fetch(`${host}/embed-2/ajax/e-1/getSources?id=${id}`, { - headers: { - "X-Requested-With": "XMLHttpRequest", - }, - }); - - const reqData = await request.json(); - - const { tracks, intro, outro } = reqData; - let { sources } = reqData; - - const req = await fetch("https://github.com/enimax-anime/key/blob/e6/key.txt"); - - const data = await req.text(); - let decryptKey = substringBefore(substringAfter(data, '"blob-code blob-code-inner js-file-line">'), ""); - if (!decryptKey) { - decryptKey = await (await fetch("https://raw.githubusercontent.com/enimax-anime/key/e6/key.txt")).json(); - } - - const encryptedURLTemp = sources.split(""); - - let key = ""; - - for (const index of decryptKey) { - for (let i = Number(index[0]); i < Number(index[1]); i++) { - key += encryptedURLTemp[i]; - encryptedURLTemp[i] = null; - } - } - - sources = encryptedURLTemp.filter((x: any) => x !== null).join(""); - - try { - sources = JSON.parse(CryptoJS.AES.decrypt(sources, key).toString(CryptoJS.enc.Utf8)); - } catch { - sources = null; - } - - if (!sources) { - return result; - } - - for (const source of sources) { - if (source.type === "hls") { - const data = await (await fetch(source.file)).text(); - - const resolutions = data.match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - - resolutions?.forEach((res: string) => { - const index = source.file.lastIndexOf("/"); - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - const url = source.file.slice(0, index); - - result.sources.push({ - url: url + "/" + res.split("\n")[1], - quality: quality + "p", - }); - }); - } - - if (intro.end > 1) { - result.intro = { - start: intro.start, - end: intro.end, - }; - } - if (outro.end > 1) { - result.outro = { - start: outro.start, - end: outro.end, - }; - } - } - - result.sources.push({ - url: sources[0].file, - quality: "auto", - }); - - result.subtitles = tracks?.map((s: any) => ({ - url: s.file, - lang: s.label ? s.label : "Thumbnails", - })); - - return result; - } - - public async extractKwik(url: string, result: Source): Promise { - const host = "https://animepahe.com"; // Subject to change maybe. - const req = await fetch(url, { headers: { Referer: host } }); - const match = load(await req.text()) - .html() - .match(/p\}.*kwik.*/g); - if (!match) { - throw new Error("Video not found."); - } - let arr: string[] = match[0].split("return p}(")[1].split(","); - - const l = arr.slice(0, arr.length - 5).join(""); - arr = arr.slice(arr.length - 5, -1); - arr.unshift(l); - - const [p, a, c, k, e, d] = arr.map((x) => x.split(".sp")[0]); - - const formatted = format(p, a, c, k, e, {}); - - const source = formatted - .match(/source=\\(.*?)\\'/g)[0] - .replace(/\'/g, "") - .replace(/source=/g, "") - .replace(/\\/g, ""); - - result.sources.push({ - url: source, - quality: "auto", - }); - - return result; - - function format(p: any, a: any, c: any, k: any, e: any, d: any) { - k = k.split("|"); - e = (c: any) => { - return (c < a ? "" : e(parseInt((c / a).toString()))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)); - }; - if (!"".replace(/^/, String)) { - while (c--) { - d[e(c)] = k[c] || e(c); - } - k = [ - (e: any) => { - return d[e]; - }, - ]; - e = () => { - return "\\w+"; - }; - c = 1; - } - while (c--) { - if (k[c]) { - p = p.replace(new RegExp("\\b" + e(c) + "\\b", "g"), k[c]); - } - } - return p; - } - } - - public async extractStreamTape(url: string, result: Source): Promise { - throw new Error("Method not implemented yet."); - } - - public async extractFPlayer(url: string, result: Source): Promise { - throw new Error("Method not implemented yet."); - } - - public async extractAllAnime(url: string, result: Source): Promise { - const allAnimeApiUrl = "https://www.allanimenews.com"; - - const iframeUrl = `${allAnimeApiUrl}${url}`; - - const data = await (await fetch(iframeUrl)).json(); - const link: string = data.links[0].src; - - if (!link) return result; - - const m3u8 = await (await fetch(link)).text(); - - const resolutions = m3u8.match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - - resolutions?.forEach((res: string) => { - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - - const uri = new URL(link); - const url = uri.protocol + "//" + uri.hostname; - - result.sources.push({ - url: url + res.split("\n")[1], - quality: quality + "p", - }); - }); - - result.sources.push({ - url: link, - quality: "auto", - }); - - return result; - } -} diff --git a/anify-backend-recode/src/helper/index.ts b/anify-backend-recode/src/helper/index.ts deleted file mode 100644 index 88ec080..0000000 --- a/anify-backend-recode/src/helper/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -export function wait(time: number) { - return new Promise((resolve) => { - setTimeout(resolve, time); - }); -} - -export function substringBefore(str: string, toFind: string) { - const index = str.indexOf(toFind); - return index == -1 ? "" : str.substring(0, index); -} - -export function substringAfter(str: string, toFind: string) { - const index = str.indexOf(toFind); - return index == -1 ? "" : str.substring(index + toFind.length); -} - -export function isString(object: unknown): object is string { - return typeof object === "string"; -} - -export function setIntervalImmediately(func: () => Promise, interval: number) { - func(); - return setInterval(async () => { - try { - await func(); - } catch (e) { - console.error("Error occurred while trying to execute the interval function: ", e); - } - }, interval); -} - -export const averageMetric = (object: any) => { - let average = 0, - validCount = 0; - if (!object) return 0; - - for (const [_, v] of Object.entries(object)) { - if (v && typeof v === "number") { - average += v; - validCount++; - } - } - - return validCount === 0 ? 0 : Number.parseFloat((average / validCount).toFixed(2)); -}; diff --git a/anify-backend-recode/src/helper/stringSimilarity.ts b/anify-backend-recode/src/helper/stringSimilarity.ts deleted file mode 100644 index 81bc234..0000000 --- a/anify-backend-recode/src/helper/stringSimilarity.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { clean, sanitizeTitle } from "./title"; - -export function similarity(externalTitle: string, title: string, titleArray: string[] = []): { same: boolean; value: number } { - if (!title) { - title = ""; - } - let simi = compareTwoStrings(sanitizeTitle(title.toLowerCase()), externalTitle.toLowerCase()); - titleArray.forEach((el) => { - if (el) { - const tempSimi = compareTwoStrings(title.toLowerCase(), el.toLowerCase()); - if (tempSimi > simi) simi = tempSimi; - } - }); - let found = false; - if (simi > 0.6) { - found = true; - } - - return { - same: found, - value: simi, - }; -} - -// From npm package string-similarity -export function compareTwoStrings(first: string, second: string): number { - first = first.replace(/\s+/g, ""); - second = second.replace(/\s+/g, ""); - - if (first === second) return 1; // identical or empty - if (first.length < 2 || second.length < 2) return 0; // if either is a 0-letter or 1-letter string - - const firstBigrams = new Map(); - for (let i = 0; i < first.length - 1; i++) { - const bigram = first.substring(i, i + 2); - const count = firstBigrams.has(bigram) ? firstBigrams.get(bigram) + 1 : 1; - - firstBigrams.set(bigram, count); - } - - let intersectionSize = 0; - for (let i = 0; i < second.length - 1; i++) { - const bigram = second.substring(i, i + 2); - const count = firstBigrams.has(bigram) ? firstBigrams.get(bigram) : 0; - - if (count > 0) { - firstBigrams.set(bigram, count - 1); - intersectionSize++; - } - } - - return (2.0 * intersectionSize) / (first.length + second.length - 2); -} - -export function findBestMatch(mainString: string, targetStrings: string[]): StringResult { - if (!areArgsValid(mainString, targetStrings)) { - throw new Error("Bad arguments: First argument should be a string, second should be an array of strings"); - } - - const ratings: { target: string; rating: number }[] = []; - let bestMatchIndex = 0; - - for (let i = 0; i < targetStrings.length; i++) { - const currentTargetString: string = targetStrings[i]; - const currentRating: number = compareTwoStrings(mainString, currentTargetString); - ratings.push({ target: currentTargetString, rating: currentRating }); - if (currentRating > ratings[bestMatchIndex].rating) { - bestMatchIndex = i; - } - } - - const bestMatch = ratings[bestMatchIndex]; - - return { ratings: ratings, bestMatch: bestMatch, bestMatchIndex: bestMatchIndex }; -} - -export function findBestMatchArray(mainStrings: string[], targetStrings: string[]): StringResult { - const mainStringResults: StringResult[] = []; - - mainStrings.forEach((mainString) => { - const ratings: { target: string; rating: number; main: string }[] = []; - let bestMatchIndex = 0; - - for (let i = 0; i < targetStrings.length; i++) { - const currentTargetString: string = targetStrings[i]; - const currentRating: number = compareTwoStrings(mainString, currentTargetString); - ratings.push({ target: currentTargetString, rating: currentRating, main: mainString }); - - if (currentRating > ratings[bestMatchIndex].rating) { - bestMatchIndex = i; - } - } - - mainStringResults.push({ - ratings: ratings, - bestMatch: ratings[bestMatchIndex], - bestMatchIndex: bestMatchIndex, - }); - }); - - let overallBestMatchIndex = 0; - for (let i = 1; i < mainStringResults.length; i++) { - if (mainStringResults[i].bestMatch.rating > mainStringResults[overallBestMatchIndex].bestMatch.rating) { - overallBestMatchIndex = i; - } - } - - return mainStringResults[overallBestMatchIndex]; -} - -export function findBestMatch2DArray(mainStrings: string[], targetStrings: string[][]): StringResult { - let overallBestMatch: StringResult = { - ratings: [], - bestMatch: { target: "", rating: 0 }, - bestMatchIndex: 0, - }; - - mainStrings.forEach((mainString) => { - targetStrings.forEach((targetArray, targetArrayIndex) => { - const ratings: Array<{ target: string; rating: number }> = []; - - targetArray.forEach((targetString) => { - const currentRating = compareTwoStrings(clean(mainString.toLowerCase().trim()), clean(targetString).toLowerCase().trim()); - - ratings.push({ target: targetString, rating: currentRating }); - }); - - const bestMatchIndex = ratings.reduce((bestIndex, x, i, arr) => (x.rating > arr[bestIndex].rating ? i : bestIndex), 0); - - if (ratings[bestMatchIndex].rating > overallBestMatch.bestMatch.rating) { - overallBestMatch = { - ratings, - bestMatch: ratings[bestMatchIndex], - bestMatchIndex: targetArrayIndex, - }; - } - }); - }); - - return overallBestMatch; -} -function areArgsValid(mainString: string, targetStrings: string[]): boolean { - if (typeof mainString !== "string") return false; - if (!Array.isArray(targetStrings)) return false; - if (!targetStrings.length) return false; - if ( - targetStrings.find(function (s) { - return typeof s !== "string"; - }) - ) - return false; - return true; -} - -interface StringResult { - ratings: Array<{ target: string; rating: number }>; - bestMatch: { target: string; rating: number }; - bestMatchIndex: number; -} diff --git a/anify-backend-recode/src/helper/title.ts b/anify-backend-recode/src/helper/title.ts deleted file mode 100644 index 33b6dcd..0000000 --- a/anify-backend-recode/src/helper/title.ts +++ /dev/null @@ -1,121 +0,0 @@ -export function clean(title: string) { - return transformSpecificVariations( - removeSpecialChars( - title - ?.replaceAll(/[^A-Za-z0-9!@#$%^&*() ]/gim, " ") - .replaceAll(/(th|rd|nd|st) (Season|season)/gim, "") - .replaceAll(/\([^\(]*\)$/gim, "") - .replaceAll("season", "") - .replaceAll(" ", " ") - .replaceAll('"', "") - .trimEnd(), - ), - ); -} - -export function removeSpecialChars(title: string) { - return title - ?.replaceAll(/[^A-Za-z0-9!@#$%^&*()\-= ]/gim, " ") - .replaceAll(/[^A-Za-z0-9\-= ]/gim, "") - .replaceAll(" ", " "); -} - -export function transformSpecificVariations(title: string) { - return title?.replaceAll("yuu", "yu").replaceAll(" ou", " oh"); -} - -export function sanitizeTitle(title: string): string { - let resTitle = title.replace(/ *(\(dub\)|\(sub\)|\(uncensored\)|\(uncut\)|\(subbed\)|\(dubbed\))/i, ""); - resTitle = resTitle.replace(/ *\([^)]+audio\)/i, ""); - resTitle = resTitle.replace(/ BD( |$)/i, ""); - resTitle = resTitle.replace(/\(TV\)/g, ""); - resTitle = resTitle.trim(); - resTitle = resTitle.substring(0, 99); // truncate - return resTitle; -} - -export const slugify = (...args: (string | number)[]): string => { - const defaultReplacements = [ - ["[aàáâãäåāăąǻάαа]", "a"], - ["[bбḃ]", "b"], - ["[cçćĉċčћ]", "c"], - ["[dðďđδдђḋ]", "d"], - ["[eèéêëēĕėęěέεеэѐё]", "e"], - ["[fƒφфḟ]", "f"], - ["[gĝğġģγгѓґ]", "g"], - ["[hĥħ]", "h"], - ["[iìíîïĩīĭįıΐήίηιϊийіїѝ]", "i"], - ["[jĵј]", "j"], - ["[kķĸκкќ]", "k"], - ["[lĺļľŀłλл]", "l"], - ["[mμмṁ]", "m"], - ["[nñńņňʼnŋνн]", "n"], - ["[oòóôõöōŏőοωόώо]", "o"], - ["[pπпṗ]", "p"], - ["q", "q"], - ["[rŕŗřρр]", "r"], - ["[sśŝşšſșςσсṡ]", "s"], - ["[tţťŧțτтṫ]", "t"], - ["[uùúûüũūŭůűųуў]", "u"], - ["[vβв]", "v"], - ["[wŵẁẃẅ]", "w"], - ["[xξ]", "x"], - ["[yýÿŷΰυϋύыỳ]", "y"], - ["[zźżžζз]", "z"], - ["[æǽ]", "ae"], - ["[χч]", "ch"], - ["[ѕџ]", "dz"], - ["fi", "fi"], - ["fl", "fl"], - ["я", "ia"], - ["[ъє]", "ie"], - ["ij", "ij"], - ["ю", "iu"], - ["х", "kh"], - ["љ", "lj"], - ["њ", "nj"], - ["[øœǿ]", "oe"], - ["ψ", "ps"], - ["ш", "sh"], - ["щ", "shch"], - ["ß", "ss"], - ["[þθ]", "th"], - ["ц", "ts"], - ["ж", "zh"], - - // White_Space, General_Category=Dash_Punctuation and Control Codes - ["[\\u0009-\\u000D\\u001C-\\u001F\\u0020\\u002D\\u0085\\u00A0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000\\u058A\\u05BE\\u1400\\u1806\\u2010-\\u2015\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D]", "-"], - ]; - - const replaceLoweringCase = (string: string, [regExp, replacement]: any) => string.replace(RegExp(regExp, "giu"), replacement); - - let value = args.join(" "); - - defaultReplacements.forEach(([a, b]) => { - value = replaceLoweringCase(value, [a, b]); - }); - - return value - .normalize("NFD") - .replace(/[\u0300-\u036f]/g, "-") - .toLowerCase() - .trim() - .replace(/[^a-z0-9 ]/g, "-") - .replace(/\s+/g, "-"); -}; - -export function stringSearch(string: string, pattern: string): number { - let count = 0; - string = string.toLowerCase(); - pattern = pattern.toLowerCase(); - string = string.replace(/[^a-zA-Z0-9 -]/g, ""); - pattern = pattern.replace(/[^a-zA-Z0-9 -]/g, ""); - - for (let i = 0; i < string.length; i++) { - for (let j = 0; j < pattern.length; j++) { - if (pattern[j] !== string[i + j]) break; - if (j === pattern.length - 1) count++; - } - } - return count; -} diff --git a/anify-backend-recode/src/index.ts b/anify-backend-recode/src/index.ts deleted file mode 100644 index 3d5216f..0000000 --- a/anify-backend-recode/src/index.ts +++ /dev/null @@ -1,94 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; -import { Format, MediaStatus, Type } from "./types/enums"; -import { init } from "./database"; -import emitter, { Events } from "./lib"; -import { get } from "./database/impl/modify/get"; -import queues from "./worker"; -import { start } from "./server"; -import { mangaProviders } from "./mappings"; -import { loadPDF } from "./lib/impl/pdf"; -import { loadMapping } from "./lib/impl/mappings"; -import { fetchChapters } from "./content/impl/chapters"; - -before().then(async (_) => { - //await start(); - const chapter = { - id: "/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1", - title: "Chapter 1", - number: 1, - updatedAt: 1660688888000, - }; - - const pages = await mangaProviders.mangasee.fetchPages("/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1"); - - await loadPDF({ id: "dc481ed5-4925-4f3c-bac1-e73f1e7ed338", providerId: "mangasee", chapter, pages: pages ?? [] }).then(console.log); -}); - -async function before() { - await fetchCorsProxies(); - await init(); - - emitter.on(Events.COMPLETED_MAPPING_LOAD, async (data) => { - for (let i = 0; i < data.length; i++) { - if (await get(String(data[i].id))) { - continue; - } - queues.createEntry.add({ toInsert: data[i], type: data[i].type }); - } - }); - - emitter.on(Events.COMPLETED_SEARCH_LOAD, (data) => { - for (let i = 0; i < data.length; i++) { - if (data[i].status === MediaStatus.NOT_YET_RELEASED) { - continue; - } - queues.mappingQueue.add({ id: data[i].id, type: data[i].type, formats: [data[i].format] }); - } - }); - - emitter.on(Events.COMPLETED_SEASONAL_LOAD, async (data) => { - for (let i = 0; i < data.trending.length; i++) { - if (data.trending[i].status === MediaStatus.NOT_YET_RELEASED) { - continue; - } - const existing = await get(String(data.trending[i].id)); - if (!existing) { - queues.mappingQueue.add({ id: data.trending[i].id, type: data.trending[i].type, formats: [data.trending[i].format] }); - } - } - - for (let i = 0; i < data.popular.length; i++) { - if (data.popular[i].status === MediaStatus.NOT_YET_RELEASED) { - continue; - } - const existing = await get(String(data.popular[i].id)); - if (!existing) queues.mappingQueue.add({ id: data.popular[i].id, type: data.popular[i].type, formats: [data.popular[i].format] }); - } - - for (let i = 0; i < data.top.length; i++) { - if (data.top[i].status === MediaStatus.NOT_YET_RELEASED) { - continue; - } - const existing = await get(String(data.top[i].id)); - if (!existing) queues.mappingQueue.add({ id: data.top[i].id, type: data.top[i].type, formats: [data.top[i].format] }); - } - - for (let i = 0; i < data.seasonal.length; i++) { - if (data.seasonal[i].status === MediaStatus.NOT_YET_RELEASED) { - continue; - } - const existing = await get(String(data.seasonal[i].id)); - if (!existing) queues.mappingQueue.add({ id: data.seasonal[i].id, type: data.seasonal[i].type, formats: [data.seasonal[i].format] }); - } - }); - - queues.mappingQueue.start(); - queues.createEntry.start(); - queues.searchQueue.start(); - queues.seasonalQueue.start(); - queues.skipTimes.start(); - queues.uploadPages.start(); -} diff --git a/anify-backend-recode/src/server/index.ts b/anify-backend-recode/src/server/index.ts deleted file mode 100644 index c51afb0..0000000 --- a/anify-backend-recode/src/server/index.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { readdirSync } from "node:fs"; -import { join } from "node:path"; - -import Redis from "ioredis"; - -import colors from "colors"; - -import { env } from "../env"; - -export const redis: Redis = env.REDIS_URL - ? new Redis((env.REDIS_URL as string) || "redis://localhost:6379") - : ({ - get: async () => null, - set: (): Promise<"OK"> => Promise.resolve("OK"), - on: () => Redis.prototype, - keys: async () => [], - connect: async () => void 0, - call: async () => void 0, - } as any); - -export const cacheTime = env.REDIS_CACHE_TIME || 60 * 60 * 24 * 7 * 2; - -export const start = async () => { - const routes: { [key: string]: { path: string; handler: (req: Request) => Promise } } = {}; - const routeFiles = readdirSync(join(import.meta.dir, "./impl")); - for (const file of routeFiles) { - const routeModule = await import(join(import.meta.dir, "./impl", file)); - const route = routeModule.default; - - if (route) { - const { path, handler } = route; - routes[path] = { path, handler }; - } - } - - Bun.serve({ - port: env.PORT, - async fetch(req: Request) { - const url = new URL(req.url); - if (url.pathname === "/") return new Response("Welcome to Anify API! 🎉 Documentation can be viewed at https://docs.anify.tv. Join our Discord https://anify.tv/discord for more information.", { headers: { "Content-Type": "application/json" } }); - - const pathName = `/${url.pathname.split("/").slice(1)[0]}`; - - if (routes[pathName]) { - const { path, handler } = routes[pathName]; - return handler(req); - } - - return new Response(JSON.stringify({ error: "Route not found" }), { status: 404, headers: { "Content-Type": "application/json" } }); - }, - }); - - console.log(colors.blue(`Server is now listening on ${env.PORT}`)); -}; diff --git a/anify-backend-recode/src/worker/index.ts b/anify-backend-recode/src/worker/index.ts deleted file mode 100644 index 9331c6d..0000000 --- a/anify-backend-recode/src/worker/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import mappingQueue from "./impl/mappings"; -import createEntry from "./impl/entry"; -import searchQueue from "./impl/search"; -import seasonalQueue from "./impl/seasonal"; -import skipTimes from "./impl/skipTimes"; -import uploadPages from "./impl/pdf"; - -export default { - mappingQueue, - createEntry, - searchQueue, - seasonalQueue, - skipTimes, - uploadPages, -}; diff --git a/anify-backend-recode/tsconfig.json b/anify-backend-recode/tsconfig.json deleted file mode 100644 index 388a057..0000000 --- a/anify-backend-recode/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "preserve", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} diff --git a/anify-backend/.env.example b/anify-backend/.env.example index a0a1c9c..4a0f340 100644 --- a/anify-backend/.env.example +++ b/anify-backend/.env.example @@ -1,31 +1,20 @@ # What port to listen to -PORT="3060" -# Whether to use PostgreSQL or another database format (TBD). Must be either "postgres" or "". -DATABASE_TYPE="postgres" -# PostgreSQL database URL -DATABASE_URL="postgresql://postgres:password@localhost:5432/?connection_limit=100" -# 9anime resolver URL -NINEANIME_RESOLVER="https://9anime.resolver.com" +PORT=3060 +# Censys ID used for finding CORS proxies https://search.censys.io/account/api +CENSYS_ID="" +# Censys secret used for finding CORS proxies https://search.censys.io/account/api +CENSYS_SECRET="" +# 9anime resolver URL. Private server that can be obtained via the Consumet Discord if necessary. +# https://discord.gg/yMZTcVstD3 +NINEANIME_RESOLVER="https://9anime.myresolver.com" # 9anime resolver API key -NINEANIME_KEY="9animekey" -# Redis URL +NINEANIME_KEY="9anime" +# Redis URL. If you aren't using Redis, you can remove this from your .env file. REDIS_URL="redis://localhost:6379" -# How long to cache redis data +# Redis cache time in seconds. 18000 = 5 hours. REDIS_CACHE_TIME="18000" -# Whether to use API keys -USE_API_KEYS="true" -# Master API key for admin actions -MASTER_KEY="" -# API key whitelist -API_KEY_WHITELIST="key1,key2,key3" -# Censys ID used for finding CORS proxies https://search.censys.io/account/api -CENSYS_ID="censys_id" -# Censys secret used for finding CORS proxies https://search.censys.io/account/api -CENSYS_SECRET="censys_secret" -# Simkl API client ID -SIMKL_CLIENT_ID="simkl_client_id" -# Simkl API client secret -SIMKL_CLIENT_SECRET="simkl_client_secret" +# Simkl client ID used for querying episode covers +SIMKL_CLIENT_ID="" # Mixdrop related for uploads # Whether to use Mixdrop diff --git a/anify-backend/.gitignore b/anify-backend/.gitignore index 7f0d654..9910413 100644 --- a/anify-backend/.gitignore +++ b/anify-backend/.gitignore @@ -1,34 +1,171 @@ -node_modules -/.pnp -.pnp.js -/coverage -/prisma/db.sqlite -/prisma/db.sqlite-journal -/.next/ -/out/ -next-env.d.ts -/build -.env -.env*.local -built -.DS_Store -*.pem -npm-debug.log* +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ yarn-debug.log* yarn-error.log* +lerna-debug.log* .pnpm-debug.log* -.vercel -*.tsbuildinfo + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +\*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +\*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +\*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +\*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.cache +.parcel-cache + +# Next.js build output + .next -**/public/workbox-*.js -**/public/sw.js -**/public/sw.js.map -**/public/workbox-*.js.map -/built -/dist -manami.json -popularIds.json -PopularIds.json -database.json -/manga -bun.lockb \ No newline at end of file +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +.cache/ + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp +.cache + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.\* + +/manga \ No newline at end of file diff --git a/anify-backend/README.md b/anify-backend/README.md index 9d1ece3..6077abe 100644 --- a/anify-backend/README.md +++ b/anify-backend/README.md @@ -1,199 +1,15 @@ -# anify-backend -Robust JavaScript API server for scraping anime, manga, and light novel sites. +# test -# Information +To install dependencies: -## Scraping -Anify scrapes numerous Japanese media sites from Zoro, to MangaSee, to NovelUpdates, and more. The API is built on top of [AniSync](https://github.com/Eltik/AniSync) to map AniList information accurately, allowing for multiple providers in case one ever goes down. To avoid rate limits, the API stores information in a database to ensure fast and accurate results. This is meant to be a robust web server, so there are a ton of features from Redis caching, PostgreSQL support, configurable `.env` options, etc. -## Anime -The API supports the following anime sites: -- [x] [Zoro](https://aniwatch.to) -- [x] [GogoAnime](https://www1.gogoanime.bid/) -- [x] [AnimePahe](https://animepahe.com) -- [x] [9anime](https://9anime.pl) - -## Manga -The API supports the following manga sites: -- [x] [MangaDex](https://mangadex.org) -- [x] [ComicK](https://comick.app) -- [x] [MangaBuddy](https://mangabuddy.com) -- [x] [MangaSee](https://mangasee123.com) - -## Novels -The API supports the following novel sites: -- [x] [NovelUpdates](https://novelupdates.com) -- [x] [JNovels](https://jnovels.com) -- [x] [NovelBuddy](https://novelbuddy.com) -- [x] [ReadLightNovels](https://readlightnovels.net) - -## Meta -The API supports the following meta providers: -- [x] [Kitsu](https://kitsu.io) -- [x] [TMDB](https://www.themoviedb.org) -- [x] [TVDB](https://thetvdb.com) -- [x] [Simkl](https://simkl.com) - ----- - -# Building the Repository -If you wish to use Anify's backend for yourself, feel free to follow the instructions below. However, a fully-populated database will NOT be provided. Support can be directed to Anify's [Discord](https://anify.tv/discord). - -## Prerequisites -Anify requires at a minimum NodeJS version `16.0.0` and NPM version `8.0.0` (*untested*). For using this repository as a web server, installation is relatively simple. -1. Clone the repository via `git clone https://github.com/Eltik/Anify`. -2. `cd` into the folder (`cd anify-backend`). -3. Install `node_modules` via `npm i` or `yarn install`. -4. Setup additional dependencies such as Redis and PostgreSQL before starting the server (see below). -5. Run `npm run dev` to start the web server. - -## .env File -You can configure the web server via a `.env` file (not included). Default values are shown below. The only required values are the `DATABASE_URL` and `REDIS_URL`. You may change the values below to your liking: -``` -# What port to listen to -PORT="3060" -# PostgreSQL database URL -DATABASE_URL="postgresql://postgres:password@localhost:5432/?connection_limit=100" -# 9anime resolver URL -NINEANIME_RESOLVER="https://9anime.resolver.com" -# 9anime resolver API key -NINEANIME_KEY="9animekey" -# Redis URL -REDIS_URL="redis://localhost:6379" -# How long to cache redis data -REDIS_CACHE_TIME="18000" -# How long to cache redis data -REDIS_CACHE_TIME="18000" -# Whether to use API keys -USE_API_KEYS="true" -# Master API key for admin actions -MASTER_KEY="" -# API key whitelist -API_KEY_WHITELIST="key1,key2,key3" -# Censys ID used for finding CORS proxies https://search.censys.io/account/api -CENSYS_ID="censys_id" -# Censys secret used for finding CORS proxies https://search.censys.io/account/api -CENSYS_SECRET="censys_secret" -# Simkl API client ID -SIMKL_CLIENT_ID="simkl_client_id" -# Simkl API client secret -SIMKL_CLIENT_SECRET="simkl_client_secret" - -# Mixdrop related for uploads -# Whether to use Mixdrop -USE_MIXDROP="true" -# Mixdrop Email -MIXDROP_EMAIL="myemail@outlook.com" -# Mixdrop API key -MIXDROP_KEY="mixdrop_key" -``` - -## Using Redis -It is highly recommended that you use Redis for caching. On MacOS, you can install Redis via Homebrew like this: ```bash -# Installation -brew install redis - -# Start the server via Homebrew -brew services start redis - -# Start the server via the CLI -redis-server - -# Flush everything from the cache -redis-cli flushall +bun install ``` -For Linux: -```bash -# Prerequisite -sudo apt install lsb-release -# Installation -curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg -echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list -sudo apt-get update -sudo apt-get install redis +To run: -#Start the server via the CLI -redis-server -``` - -## Using PostegreSQL -By default, Anify uses [Prisma](https://npmjs.com/package/prisma) and [PostgreSQL](http://postgresql.org). PostgreSQL is used to make database querying, searching, etc. a lot easier. The prisma schema is located below. ```bash -├── node_modules -├── prisma -│ └── schema.prisma -├── package.json -└── other_files_here -``` -Put `DATABASE_URL="postgresql://postgres:password@localhost:3306"` in the `.env` file. You can change the database URL to whatever you want, but make sure to change the `database_url` in the options path to match the URL in the `.env` file. -```bash -# .env -# The URL is formatted as postgres://{username}:{password}@{host}:{port}/{database_name} -DATABASE_URL="postgres://username:password@localhost:5432/anify" - -# Here is an example that I use -DATABASE_URL="postgresql://postgres:password@localhost:3306" +bun run index.ts ``` -On MacOS, you can install PostgreSQL via [Homebrew](https://brew.sh/): -```bash -# Installation -brew install postgresql -brew install postgis - -# Start the server -brew services start postgresql - -# Stop the server -brew services stop postgresql -``` -On Linux, you can install PostgreSQL via this: -```bash -# Installation -sudo apt update -# Custom functions/pg_trgm -sudo apt install postgresql postgresql-contrib -sudo apt-get install postgresql-contrib - -# Start the server -sudo systemctl start postgresql.service - -# Stop the server -sudo systemctl stop postgresql.service -``` -[This](https://www.postgresql.org/download/linux/ubuntu/) is helpful for installation. Make sure you install at least version 15.
    -You can then run `sudo -u postgres psql` and execute commands from there. For example, for creating a new role: -```bash -sudo -u postgres psql createuser --interactive -``` -Please note that for searching via PostgreSQL, you need to get into the PSQL shell via `psql` and run: -```sql -CREATE EXTENSION IF NOT EXISTS "pg_trgm"; - -create or replace function most_similar(text, text[]) returns double precision -language sql as $$ - select max(similarity($1,x)) from unnest($2) f(x) -$$; -``` -The `db:extensions` script (see below) runs these for you, but it is recommended that you execute the scripts in your terminal just in case the script fails.
    -FYI, if you have an issue running `psql` saying, "role root does not exist", run this: -```bash -sudo -i -u postgres -psql -``` -Alternatively, you can try: -```bash -psql postgres -``` -And then update the `.env` file with the correct database URL.
    -Then, run the command: -```bash -npm run build:db -``` -If you need help with development, join our [Discord](https://anify.tv/discord) and view the [#help](https://discord.com/channels/950964096600252507/1071533139631026287) channel. - -## Contribution -This project is a work-in-progress, so contribution would be appreciated. If you'd like to contribute, feel free to open a [Pull Request](https://github.com/Eltik/Anify/pulls). -# TBD -The README for this project isn't done! Join our [Discord](https://anify.tv/discord) for more information. \ No newline at end of file +This project was created using `bun init` in bun v0.8.1. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/anify-backend-recode/db.sqlite b/anify-backend/db.sqlite similarity index 100% rename from anify-backend-recode/db.sqlite rename to anify-backend/db.sqlite diff --git a/anify-backend/package-lock.json b/anify-backend/package-lock.json index 36309bd..5b6026b 100644 --- a/anify-backend/package-lock.json +++ b/anify-backend/package-lock.json @@ -1,4729 +1,43 @@ { - "name": "anify-backend", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "anify-backend", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@extractus/article-extractor": "^8.0.2", - "@prisma/client": "^4.15.0", - "@types/probe-image-size": "^7.2.0", - "bun": "^0.8.1", - "cheerio": "1.0.0-rc.12", - "colors": "^1.4.0", - "crypto-js": "^4.1.1", - "dotenv": "^16.1.4", - "eslint": "^8.45.0", - "eventemitter2": "^6.4.9", - "form-data": "^4.0.0", - "ioredis": "^5.3.2", - "pdfkit": "^0.13.0", - "probe-image-size": "^7.2.3", - "rate-limit-redis": "^3.0.2" - }, - "bin": { - "anify-backend": "dist/index.js" - }, - "devDependencies": { - "@types/node": "^18.16.16", - "@types/pdfkit": "^0.12.10", - "@typescript-eslint/eslint-plugin": "^5.59.8", - "@typescript-eslint/parser": "^5.59.8", - "bun-types": "^0.8.1", - "copyfiles": "^2.4.1", - "prettier": "2.8.8", - "prisma": "^5.0.0", - "prisma-json-types-generator": "^2.4.0", - "rimraf": "^5.0.1", - "ts-node": "^10.9.1", - "tslib": "^2.5.3", - "typescript": "^5.2.2" - } - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/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, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "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, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@eslint/eslintrc/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==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@extractus/article-extractor": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@extractus/article-extractor/-/article-extractor-8.0.2.tgz", - "integrity": "sha512-z1Kde0H6U4y8v8VbQaxaE4RliMOrVIS/KUmoRmQ7cJn9N2OPFT5K5pucRml3DCWjyEFftLmVQzJDdo3HLLMCzQ==", - "dependencies": { - "@mozilla/readability": "^0.4.4", - "bellajs": "^11.1.2", - "cross-fetch": "^4.0.0", - "linkedom": "^0.15.1", - "sanitize-html": "2.11.0" - }, - "engines": { - "node": ">= 15" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "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==", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" - }, - "node_modules/@ioredis/commands": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", - "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", - "license": "MIT" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "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, - "license": "MIT" - }, - "node_modules/@mozilla/readability": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@mozilla/readability/-/readability-0.4.4.tgz", - "integrity": "sha512-MCgZyANpJ6msfvVMi6+A0UAsvZj//4OHREYUB9f2087uXHVoU+H+SWhuihvb1beKpM323bReQPRio0WNk2+V6g==", - "license": "Apache-2.0", - "engines": { - "node": ">=14.0.0" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "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==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@oven/bun-darwin-aarch64": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-0.8.1.tgz", - "integrity": "sha512-rdZ4vqDckP/vKjpz5TIEcj45KxIizS6k5dYO6KUOu2nlMwy+JRAE1wfrKY8qAelQ+nE96VYurD8BjkgKQiR4Iw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oven/bun-darwin-x64": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-0.8.1.tgz", - "integrity": "sha512-/pys7zKcb9A8uTXXZP08iH+0RzHBTqnuBOoG7jtwIOiGwVYbXk47KhEUoAjnexxa+rOL2EuDk8uGeo5YQHe19Q==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oven/bun-darwin-x64-baseline": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-0.8.1.tgz", - "integrity": "sha512-dSKtbLJ543EqKXgtwKW0h2IjKeInCbpp71GBNKch2azlIl/OSiUDH8xX1XBPq77BjOKSvTv+Morz8TQIFmkXAw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oven/bun-linux-aarch64": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-0.8.1.tgz", - "integrity": "sha512-7jTOMZOfWqBm7x4wreh1y9qW9zelUKXNMI+lQRym47LTaHzNs0bSQlfQuARrMaDFjfCsfOP5ks5ALAWwLVxcsw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oven/bun-linux-x64": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-0.8.1.tgz", - "integrity": "sha512-rSYtKj8yxXHzpZ4u8jclHLsbeqldaN1coLjOzs+1q+4mYJXqY5NiJRriPLya3fsSDXnZ9k2h9w0LWvW9ASnUtg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oven/bun-linux-x64-baseline": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-0.8.1.tgz", - "integrity": "sha512-6wYxr+UD/4vH0r3/weoXaJt4LndcCx9PHNeMlPSDJj+xCytQwkSSz5TCSPTlrs6a4iURs8N5+YJAb1kJ71uG5w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@prisma/client": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.15.0.tgz", - "integrity": "sha512-xnROvyABcGiwqRNdrObHVZkD9EjkJYHOmVdlKy1yGgI+XOzvMzJ4tRg3dz1pUlsyhKxXGCnjIQjWW+2ur+YXuw==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@prisma/engines-version": "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944" - }, - "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "prisma": "*" - }, - "peerDependenciesMeta": { - "prisma": { - "optional": true + "name": "test", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "test", + "dependencies": { + "eventemitter2": "^6.4.9" + }, + "devDependencies": { + "bun-types": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + } + }, + "node_modules/bun-types": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-0.8.1.tgz", + "integrity": "sha512-VuCBox66P/3a8gVOffLCWIS6vdpXq4y3eJuF3VnsyC5HpykmIjkcr5wYDn22qQdeTUmOfCcBy1SZmtrZCeUr3A==", + "dev": true + }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } } - } - }, - "node_modules/@prisma/debug": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-4.13.0.tgz", - "integrity": "sha512-JrltTewF/paRb5mcM5OvcEi9DtdX0sINOAswruxKQrwOLA7Phqb52OfY38MIzGrsrJ8iUGVqQ5bpYZYpxOGCsQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/debug": "4.1.7", - "debug": "4.3.4", - "strip-ansi": "6.0.1" - } - }, - "node_modules/@prisma/engines": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.0.0.tgz", - "integrity": "sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==", - "devOptional": true, - "hasInstallScript": true - }, - "node_modules/@prisma/engines-version": { - "version": "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944.tgz", - "integrity": "sha512-sVOig4tjGxxlYaFcXgE71f/rtFhzyYrfyfNFUsxCIEJyVKU9rdOWIlIwQ2NQ7PntvGnn+x0XuFo4OC1jvPJKzg==", - "license": "Apache-2.0" - }, - "node_modules/@prisma/generator-helper": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.13.0.tgz", - "integrity": "sha512-Zx9rtbsEIU/9DKnGRvmjLdyeyhzeeXNFp1alkRh1w//rQ5jTcobiay/jU4Qo+EQOs2bnWEfUeiBoOjfaysdLNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "4.13.0", - "@types/cross-spawn": "6.0.2", - "chalk": "4.1.2", - "cross-spawn": "7.0.3" - } - }, - "node_modules/@swc/helpers": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.3.17.tgz", - "integrity": "sha512-tb7Iu+oZ+zWJZ3HJqwx8oNwSDIU440hmVMDPhpACWQWnrZHK99Bxs70gT1L2dnr5Hg50ZRWEFkQCAnOVVV0z1Q==", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "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, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/cross-spawn": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", - "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/needle": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@types/needle/-/needle-3.2.0.tgz", - "integrity": "sha512-6XzvzEyJ2ozFNfPajFmqH9JOt0Hp+9TawaYpJT59iIP/zR0U37cfWCRwosyIeEBBZBi021Osq4jGAD3AOju5fg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/node": { - "version": "18.16.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.16.tgz", - "integrity": "sha512-NpaM49IGQQAUlBhHMF82QH80J08os4ZmyF9MkpCzWAGuOHqE4gTEbhzd7L3l5LmWuZ6E0OiC1FweQ4tsiW35+g==", - "license": "MIT" - }, - "node_modules/@types/pdfkit": { - "version": "0.12.10", - "resolved": "https://registry.npmjs.org/@types/pdfkit/-/pdfkit-0.12.10.tgz", - "integrity": "sha512-DPqNCuLXj50NehiFehndH+fzQLzb2fwHOLOvG+Zsm7rJBHgpMLeJrB4eC3RQf7Zl1uiWVYyBuFqVbZnveUb4mA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/probe-image-size": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/probe-image-size/-/probe-image-size-7.2.0.tgz", - "integrity": "sha512-R5H3vw62gHNHrn+JGZbKejb+Z2D/6E5UNVlhCzIaBBLroMQMOFqy5Pap2gM+ZZHdqBtVU0/cx/M6to+mOJcoew==", - "dependencies": { - "@types/needle": "*", - "@types/node": "*" - } - }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz", - "integrity": "sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/type-utils": "5.59.8", - "@typescript-eslint/utils": "5.59.8", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz", - "integrity": "sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/typescript-estree": "5.59.8", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", - "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz", - "integrity": "sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.8", - "@typescript-eslint/utils": "5.59.8", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", - "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", - "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", - "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/typescript-estree": "5.59.8", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", - "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "peer": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "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==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT", - "peer": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "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/bellajs": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/bellajs/-/bellajs-11.1.2.tgz", - "integrity": "sha512-2Fy3Km5JKyIy/KunW3oica2gZtkjD2qSqti2Q3xPhHvXXdMbc+32pEMOPG+xrSat0BXVhRjHIx++lzxIPK0GqQ==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brotli": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", - "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", - "license": "MIT", - "dependencies": { - "base64-js": "^1.1.2" - } - }, - "node_modules/bun": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/bun/-/bun-0.8.1.tgz", - "integrity": "sha512-bWVEO9ipiG00dSOtCd/iGZ+LyxuO8l1SBE9uExg/npUQpC0B/ZQlK3whnV05grOd5gQ0wY4oxO75Csdt+g3VZA==", - "cpu": [ - "arm64", - "x64" - ], - "hasInstallScript": true, - "os": [ - "darwin", - "linux" - ], - "bin": { - "bun": "bin/bun", - "bunx": "bin/bun" - }, - "optionalDependencies": { - "@oven/bun-darwin-aarch64": "0.8.1", - "@oven/bun-darwin-x64": "0.8.1", - "@oven/bun-darwin-x64-baseline": "0.8.1", - "@oven/bun-linux-aarch64": "0.8.1", - "@oven/bun-linux-x64": "0.8.1", - "@oven/bun-linux-x64-baseline": "0.8.1" - } - }, - "node_modules/bun-types": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-0.8.1.tgz", - "integrity": "sha512-VuCBox66P/3a8gVOffLCWIS6vdpXq4y3eJuF3VnsyC5HpykmIjkcr5wYDn22qQdeTUmOfCcBy1SZmtrZCeUr3A==", - "dev": true - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "license": "MIT", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT", - "peer": true - }, - "node_modules/copyfiles": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", - "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^7.0.5", - "minimatch": "^3.0.3", - "mkdirp": "^1.0.4", - "noms": "0.0.0", - "through2": "^2.0.1", - "untildify": "^4.0.0", - "yargs": "^16.1.0" - }, - "bin": { - "copyfiles": "copyfiles", - "copyup": "copyfiles" - } - }, - "node_modules/copyfiles/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==", - "license": "MIT" - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-equal": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz", - "integrity": "sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.1", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/deep-equal/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "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==" - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/dfa": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", - "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==" - }, - "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, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "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", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dotenv": { - "version": "16.1.4", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", - "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT", - "peer": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-get-iterator/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT", - "peer": true - }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", - "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter2": { - "version": "6.4.9", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", - "license": "MIT" - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-rate-limit": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.7.0.tgz", - "integrity": "sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 12.9.0" - }, - "peerDependencies": { - "express": "^4 || ^5" - } - }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "license": "MIT", - "peer": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT", - "peer": true - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "license": "MIT", - "peer": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/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==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "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==", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "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, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT", - "peer": true - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" - }, - "node_modules/fontkit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-1.9.0.tgz", - "integrity": "sha512-HkW/8Lrk8jl18kzQHvAw9aTHe1cqsyx5sDnxncx652+CIfhawokEPkeM3BoIC+z/Xv7a0yMr0f3pRRwhGH455g==", - "dependencies": { - "@swc/helpers": "^0.3.13", - "brotli": "^1.3.2", - "clone": "^2.1.2", - "deep-equal": "^2.0.5", - "dfa": "^1.2.0", - "restructure": "^2.0.1", - "tiny-inflate": "^1.0.3", - "unicode-properties": "^1.3.1", - "unicode-trie": "^2.0.0" - } - }, - "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==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "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", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "license": "MIT" - }, - "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==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "license": "ISC", - "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": "*" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "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/globby/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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/globby/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, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/globby/node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "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/globby/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/globby/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/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.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==", - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/html-escaper": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", - "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" - }, - "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", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ioredis": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz", - "integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==", - "license": "MIT", - "dependencies": { - "@ioredis/commands": "^1.1.1", - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.4", - "denque": "^2.1.0", - "lodash.defaults": "^4.2.0", - "lodash.isarguments": "^3.1.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" - }, - "engines": { - "node": ">=12.22.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ioredis" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "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==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jackspeak": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", - "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" - }, - "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==", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/linebreak": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz", - "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==", - "dependencies": { - "base64-js": "0.0.8", - "unicode-trie": "^2.0.0" - } - }, - "node_modules/linebreak/node_modules/base64-js": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", - "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/linkedom": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.15.3.tgz", - "integrity": "sha512-p+lBSEWzawF3Gy7+nw+5+u+iDthsfZZVd9lwiO96Ihj7Zd8he5BD1Wzdc9Z4GqtU6lKvxhye4W4Zr20uOAGe4A==", - "dependencies": { - "css-select": "^5.1.0", - "cssom": "^0.5.0", - "html-escaper": "^3.0.3", - "htmlparser2": "^8.0.1", - "uhyphen": "^0.2.0" - } - }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", - "license": "MIT" - }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", - "license": "MIT" - }, - "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==" - }, - "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==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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, - "license": "ISC" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "license": "MIT", - "peer": 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, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "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, - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "peer": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true, - "license": "MIT" - }, - "node_modules/needle": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", - "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", - "dependencies": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "bin": { - "needle": "bin/needle" - }, - "engines": { - "node": ">= 4.4.x" - } - }, - "node_modules/needle/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/noms": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", - "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", - "dev": true, - "license": "ISC", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "~1.0.31" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "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==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "peer": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-srcset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", - "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "license": "MIT", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", - "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "license": "MIT", - "peer": true - }, - "node_modules/pdfkit": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/pdfkit/-/pdfkit-0.13.0.tgz", - "integrity": "sha512-AW79eHU5eLd2vgRDS9z3bSoi0FA+gYm+100LLosrQQMLUzOBGVOhG7ABcMFpJu7Bpg+MT74XYHi4k9EuU/9EZw==", - "dependencies": { - "crypto-js": "^4.0.0", - "fontkit": "^1.8.1", - "linebreak": "^1.0.2", - "png-js": "^1.0.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==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/png-js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz", - "integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==" - }, - "node_modules/postcss": { - "version": "8.4.29", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", - "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "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==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prisma": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.0.0.tgz", - "integrity": "sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA==", - "devOptional": true, - "hasInstallScript": true, - "dependencies": { - "@prisma/engines": "5.0.0" - }, - "bin": { - "prisma": "build/index.js" - }, - "engines": { - "node": ">=16.13" - } - }, - "node_modules/prisma-json-types-generator": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-2.4.0.tgz", - "integrity": "sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@prisma/generator-helper": "^4.10.1", - "tslib": "^2.5.0" - }, - "bin": { - "prisma-json-types-generator": "dist/bin.js" - }, - "engines": { - "node": ">=14.0" - }, - "funding": { - "url": "https://github.com/ArthurFiorette/prisma-json-types-generator?sponsor=1" - } - }, - "node_modules/probe-image-size": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.2.3.tgz", - "integrity": "sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==", - "dependencies": { - "lodash.merge": "^4.6.2", - "needle": "^2.5.2", - "stream-parser": "~0.3.1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "peer": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/rate-limit-redis": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-3.0.2.tgz", - "integrity": "sha512-4SBK6AzIr9PKkCF4HmSDcJH2O2KKMF3fZEcsbNMXyaL5I9d6X71uOreUldFRiyrRyP+qkQrTxzJ38ZKKN+sScw==", - "license": "MIT", - "engines": { - "node": ">= 14.5.0" - }, - "peerDependencies": { - "express-rate-limit": "^6" - } - }, - "node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/readable-stream/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", - "license": "MIT", - "dependencies": { - "redis-errors": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/restructure": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/restructure/-/restructure-2.0.1.tgz", - "integrity": "sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg==" - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^10.2.5" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.2.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz", - "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "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==", - "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", - "peer": true - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/sanitize-html": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.11.0.tgz", - "integrity": "sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==", - "dependencies": { - "deepmerge": "^4.2.2", - "escape-string-regexp": "^4.0.0", - "htmlparser2": "^8.0.0", - "is-plain-object": "^5.0.0", - "parse-srcset": "^1.0.2", - "postcss": "^8.3.11" - } - }, - "node_modules/sanitize-html/node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT", - "peer": true - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT", - "peer": true - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "license": "MIT", - "peer": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC", - "peer": true - }, - "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==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/standard-as-callback": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", - "license": "MIT" - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/stream-parser": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", - "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==", - "dependencies": { - "debug": "2" - } - }, - "node_modules/stream-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/stream-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "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" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "license": "MIT" - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/tiny-inflate": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", - "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" - }, - "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, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/to-regex-range/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, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "license": "MIT", - "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/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "license": "0BSD" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "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==", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "peer": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/uhyphen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz", - "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==" - }, - "node_modules/unicode-properties": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz", - "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==", - "dependencies": { - "base64-js": "^1.3.0", - "unicode-trie": "^2.0.0" - } - }, - "node_modules/unicode-trie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", - "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", - "dependencies": { - "pako": "^0.2.5", - "tiny-inflate": "^1.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "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, - "license": "MIT" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "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/whatwg-url": { - "version": "5.0.0", - "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/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "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==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", - "dependencies": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "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/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "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, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "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==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } - } } diff --git a/anify-backend/package.json b/anify-backend/package.json index 060611e..4b6355f 100644 --- a/anify-backend/package.json +++ b/anify-backend/package.json @@ -1,79 +1,36 @@ { - "devDependencies": { - "@types/node": "^18.16.16", - "@types/pdfkit": "^0.12.10", - "@typescript-eslint/eslint-plugin": "^5.59.8", - "@typescript-eslint/parser": "^5.59.8", - "bun-types": "^0.8.1", - "copyfiles": "^2.4.1", - "prettier": "2.8.8", - "prisma": "^5.0.0", - "prisma-json-types-generator": "^2.4.0", - "rimraf": "^5.0.1", - "ts-node": "^10.9.1", - "tslib": "^2.5.3", - "typescript": "^5.2.2" - }, - "name": "anify-backend", - "description": "Anify backend", - "version": "1.0.0", - "source": "src/index.ts", - "bin": "dist/index.js", + "name": "test", + "module": "index.ts", + "type": "module", "scripts": { + "start": "bun run dist/index.js", "dev": "bun run src/index.ts", - "crawl": "bun run src/crawl.ts", - "start": "bun run dist/index.js/index.js", - "copy-files": "copyfiles -u 1 src/**/*.json dist/", - "build": "npm run check:env && npm run build:db && npm run lint && npm run build:bun", - "rebuild": "npm run clean && npm run build:ts", - "build:bun": "bun build src/index.ts --outdir dist/index.js --target node", - "build:ts": "tsc --project tsconfig.json && npm run copy-files", - "build:db": "ts-node src/scripts/buildDb.ts", - "db:generate": "npx prisma generate", - "db:push": "npx prisma db push", - "db:validate": "npx prisma validate", - "clean": "rimraf dist/", - "export": "ts-node -r tsconfig-paths/register src/scripts/export.ts", - "clear": "ts-node -r tsconfig-paths/register src/scripts/clear.ts", - "import": "ts-node -r tsconfig-paths/register src/scripts/import.ts", - "create:key": "ts-node -r tsconfig-paths/register src/scripts/createKey.ts", - "create:proxies": "ts-node -r tsconfig-paths/register src/scripts/scrapeProxies.ts", - "check:proxies": "ts-node -r tsconfig-paths/register src/scripts/checkProxies.ts", - "check:env": "ts-node -r tsconfig-paths/register src/scripts/checkEnv.ts", - "redis:flush": "ts-node -r tsconfig-paths/register src/scripts/flushSafe.ts", + "build": "bun build ./src/index.ts --outdir ./dist --target node", "prettier": "prettier --write .", "eslint": "eslint --ext .ts src/** --fix", - "lint": "npm run prettier && npm run eslint" + "lint": "bun run prettier && bun run eslint" }, - "repository": { - "type": "git", - "url": "git+https://github.com/Eltik/Anify.git" - }, - "author": "eltik", - "license": "ISC", - "bugs": { - "url": "https://github.com/Eltik/Anify/issues" + "devDependencies": { + "@types/crypto-js": "^4.1.2", + "@types/pdfkit": "^0.12.10", + "@typescript-eslint/eslint-plugin": "latest", + "@typescript-eslint/parser": "latest", + "bun-types": "latest", + "eslint": "^8.48.0", + "prettier": "^3.0.3" }, - "homepage": "https://anify.tv", - "directories": { - "test": "test", - "lib": "src" + "peerDependencies": { + "typescript": "^5.0.0" }, "dependencies": { "@extractus/article-extractor": "^8.0.2", - "@prisma/client": "^4.15.0", - "@types/probe-image-size": "^7.2.0", - "bun": "^0.8.1", - "cheerio": "1.0.0-rc.12", + "cheerio": "^1.0.0-rc.12", "colors": "^1.4.0", "crypto-js": "^4.1.1", - "dotenv": "^16.1.4", - "eslint": "^8.45.0", - "eventemitter2": "^6.4.9", - "form-data": "^4.0.0", + "dotenv": "^16.3.1", + "eventemitter2": "latest", + "image-size": "^1.0.2", "ioredis": "^5.3.2", - "pdfkit": "^0.13.0", - "probe-image-size": "^7.2.3", - "rate-limit-redis": "^3.0.2" + "pdfkit": "^0.13.0" } } diff --git a/anify-backend/pnpm-lock.yaml b/anify-backend/pnpm-lock.yaml deleted file mode 100644 index 21202e4..0000000 --- a/anify-backend/pnpm-lock.yaml +++ /dev/null @@ -1,5819 +0,0 @@ -lockfileVersion: '6.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -dependencies: - '@extractus/article-extractor': - specifier: ^7.2.16 - version: 7.2.16 - '@prisma/client': - specifier: ^4.15.0 - version: 4.15.0(prisma@5.0.0) - body-parser: - specifier: ^1.20.2 - version: 1.20.2 - cheerio: - specifier: 1.0.0-rc.12 - version: 1.0.0-rc.12 - cloudscraper-ts: - specifier: ^1.0.9 - version: 1.0.9 - colors: - specifier: ^1.4.0 - version: 1.4.0 - cookie-parser: - specifier: ^1.4.6 - version: 1.4.6 - cors: - specifier: ^2.8.5 - version: 2.8.5 - crypto-js: - specifier: ^4.1.1 - version: 4.1.1 - dotenv: - specifier: ^16.1.4 - version: 16.1.4 - eslint: - specifier: ^8.45.0 - version: 8.45.0 - eventemitter2: - specifier: ^6.4.9 - version: 6.4.9 - express: - specifier: ^4.18.2 - version: 4.18.2 - express-domain-middleware: - specifier: ^0.1.0 - version: 0.1.0 - express-rate-limit: - specifier: ^6.7.0 - version: 6.7.0(express@4.18.2) - ioredis: - specifier: ^5.3.2 - version: 5.3.2 - mathjs: - specifier: ^11.8.0 - version: 11.8.0 - rate-limit-redis: - specifier: ^3.0.2 - version: 3.0.2(express-rate-limit@6.7.0) - -devDependencies: - '@jest/globals': - specifier: ^29.5.0 - version: 29.5.0 - '@types/jest': - specifier: ^29.5.2 - version: 29.5.2 - '@types/node': - specifier: ^18.16.16 - version: 18.16.16 - '@typescript-eslint/eslint-plugin': - specifier: ^5.59.8 - version: 5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.45.0)(typescript@4.9.5) - '@typescript-eslint/parser': - specifier: ^5.59.8 - version: 5.59.8(eslint@8.45.0)(typescript@4.9.5) - copyfiles: - specifier: ^2.4.1 - version: 2.4.1 - jest: - specifier: ^29.5.0 - version: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - prettier: - specifier: 2.8.8 - version: 2.8.8 - prisma: - specifier: ^5.0.0 - version: 5.0.0 - prisma-json-types-generator: - specifier: ^2.4.0 - version: 2.4.0 - rimraf: - specifier: ^5.0.1 - version: 5.0.1 - ts-jest: - specifier: ^29.1.0 - version: 29.1.0(@babel/core@7.22.1)(jest@29.5.0)(typescript@4.9.5) - ts-node: - specifier: ^10.9.1 - version: 10.9.1(@types/node@18.16.16)(typescript@4.9.5) - tsconfig-paths: - specifier: ^4.2.0 - version: 4.2.0 - tscpaths: - specifier: ^0.0.9 - version: 0.0.9 - tslib: - specifier: ^2.5.3 - version: 2.5.3 - typescript: - specifier: ^4.9.5 - version: 4.9.5 - -packages: - - /@aashutoshrathi/word-wrap@1.2.6: - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - - /@ampproject/remapping@2.2.1: - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - - /@babel/code-frame@7.21.4: - resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.18.6 - - /@babel/compat-data@7.22.3: - resolution: {integrity: sha512-aNtko9OPOwVESUFp3MZfD8Uzxl7JzSeJpd7npIoxCasU37PFbAQRpKglkaKwlHOyeJdrREpo8TW8ldrkYWwvIQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/core@7.22.1: - resolution: {integrity: sha512-Hkqu7J4ynysSXxmAahpN1jjRwVJ+NdpraFLIWflgjpVob3KNyK3/tIUc7Q7szed8WMp0JNa7Qtd1E9Oo22F9gA==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.22.3 - '@babel/helper-compilation-targets': 7.22.1(@babel/core@7.22.1) - '@babel/helper-module-transforms': 7.22.1 - '@babel/helpers': 7.22.3 - '@babel/parser': 7.22.4 - '@babel/template': 7.21.9 - '@babel/traverse': 7.22.4 - '@babel/types': 7.22.4 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/generator@7.22.3: - resolution: {integrity: sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - jsesc: 2.5.2 - dev: true - - /@babel/helper-compilation-targets@7.22.1(@babel/core@7.22.1): - resolution: {integrity: sha512-Rqx13UM3yVB5q0D/KwQ8+SPfX/+Rnsy1Lw1k/UwOC4KC6qrzIQoY3lYnBu5EHKBlEHHcj0M0W8ltPSkD8rqfsQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.22.3 - '@babel/core': 7.22.1 - '@babel/helper-validator-option': 7.21.0 - browserslist: 4.21.7 - lru-cache: 5.1.1 - semver: 6.3.0 - dev: true - - /@babel/helper-environment-visitor@7.22.1: - resolution: {integrity: sha512-Z2tgopurB/kTbidvzeBrc2To3PUP/9i5MUe+fU6QJCQDyPwSH2oRapkLw3KGECDYSjhQZCNxEvNvZlLw8JjGwA==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-function-name@7.21.0: - resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.21.9 - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-hoist-variables@7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-module-imports@7.21.4: - resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-module-transforms@7.22.1: - resolution: {integrity: sha512-dxAe9E7ySDGbQdCVOY/4+UcD8M9ZFqZcZhSPsPacvCG4M+9lwtDDQfI2EoaSvmf7W/8yCBkGU0m7Pvt1ru3UZw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.22.1 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-simple-access': 7.21.5 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.21.9 - '@babel/traverse': 7.22.4 - '@babel/types': 7.22.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-plugin-utils@7.21.5: - resolution: {integrity: sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-simple-access@7.21.5: - resolution: {integrity: sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-split-export-declaration@7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-string-parser@7.21.5: - resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier@7.19.1: - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} - engines: {node: '>=6.9.0'} - - /@babel/helper-validator-option@7.21.0: - resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helpers@7.22.3: - resolution: {integrity: sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.21.9 - '@babel/traverse': 7.22.4 - '@babel/types': 7.22.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/highlight@7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.19.1 - chalk: 2.4.2 - js-tokens: 4.0.0 - - /@babel/parser@7.22.4: - resolution: {integrity: sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.1): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.1): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.1): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.22.1): - resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.1): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.1): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.1): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.22.1): - resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/runtime@7.22.3: - resolution: {integrity: sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.11 - dev: false - - /@babel/template@7.21.9: - resolution: {integrity: sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.21.4 - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - dev: true - - /@babel/traverse@7.22.4: - resolution: {integrity: sha512-Tn1pDsjIcI+JcLKq1AVlZEr4226gpuAQTsLMorsYg9tuS/kG7nuwwJ4AB8jfQuEgb/COBwR/DqJxmoiYFu5/rQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.22.3 - '@babel/helper-environment-visitor': 7.22.1 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/types@7.22.4: - resolution: {integrity: sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.21.5 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: true - - /@bcoe/v8-coverage@0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true - - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - - /@eslint-community/eslint-utils@4.4.0(eslint@8.45.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.45.0 - eslint-visitor-keys: 3.4.1 - - /@eslint-community/regexpp@4.5.1: - resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - /@eslint/eslintrc@2.1.0: - resolution: {integrity: sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.20.0 - ignore: 5.2.4 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - /@eslint/js@8.44.0: - resolution: {integrity: sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - /@extractus/article-extractor@7.2.16: - resolution: {integrity: sha512-LV55IG1QOMTDzbb4Cb6TQ8LMoh+smtr6pIAEA7IWTUw8VbSQZtRPr0Go6akJSb/XaaKv4KrtsxNyrhyAjtWrcA==} - engines: {node: '>= 14'} - dependencies: - '@mozilla/readability': 0.4.4 - bellajs: 11.1.2 - cross-fetch: 3.1.6 - linkedom: 0.14.26 - sanitize-html: 2.10.0 - transitivePeerDependencies: - - encoding - dev: false - - /@humanwhocodes/config-array@0.11.10: - resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - /@humanwhocodes/object-schema@1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - - /@ioredis/commands@1.2.0: - resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} - dev: false - - /@isaacs/cliui@8.0.2: - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - dependencies: - string-width: 5.1.2 - string-width-cjs: /string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: /strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: true - - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - dev: true - - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - dev: true - - /@jest/console@29.5.0: - resolution: {integrity: sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - slash: 3.0.0 - dev: true - - /@jest/core@29.5.0(ts-node@10.9.1): - resolution: {integrity: sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==} - 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 - dependencies: - '@jest/console': 29.5.0 - '@jest/reporters': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.8.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.5.0 - jest-config: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - jest-haste-map: 29.5.0 - jest-message-util: 29.5.0 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-resolve-dependencies: 29.5.0 - jest-runner: 29.5.0 - jest-runtime: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - jest-watcher: 29.5.0 - micromatch: 4.0.5 - pretty-format: 29.5.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - supports-color - - ts-node - dev: true - - /@jest/environment@29.5.0: - resolution: {integrity: sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/fake-timers': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - jest-mock: 29.5.0 - dev: true - - /@jest/expect-utils@29.5.0: - resolution: {integrity: sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.4.3 - dev: true - - /@jest/expect@29.5.0: - resolution: {integrity: sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - expect: 29.5.0 - jest-snapshot: 29.5.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/fake-timers@29.5.0: - resolution: {integrity: sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@sinonjs/fake-timers': 10.2.0 - '@types/node': 18.16.16 - jest-message-util: 29.5.0 - jest-mock: 29.5.0 - jest-util: 29.5.0 - dev: true - - /@jest/globals@29.5.0: - resolution: {integrity: sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.5.0 - '@jest/expect': 29.5.0 - '@jest/types': 29.5.0 - jest-mock: 29.5.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/reporters@29.5.0: - resolution: {integrity: sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==} - 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 - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 18.16.16 - chalk: 4.1.2 - collect-v8-coverage: 1.0.1 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 5.2.1 - istanbul-lib-report: 3.0.0 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.5 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - jest-worker: 29.5.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.1.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/schemas@29.4.3: - resolution: {integrity: sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@sinclair/typebox': 0.25.24 - dev: true - - /@jest/source-map@29.4.3: - resolution: {integrity: sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jridgewell/trace-mapping': 0.3.18 - callsites: 3.1.0 - graceful-fs: 4.2.11 - dev: true - - /@jest/test-result@29.5.0: - resolution: {integrity: sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.5.0 - '@jest/types': 29.5.0 - '@types/istanbul-lib-coverage': 2.0.4 - collect-v8-coverage: 1.0.1 - dev: true - - /@jest/test-sequencer@29.5.0: - resolution: {integrity: sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.5.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - slash: 3.0.0 - dev: true - - /@jest/transform@29.5.0: - resolution: {integrity: sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.22.1 - '@jest/types': 29.5.0 - '@jridgewell/trace-mapping': 0.3.18 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - jest-regex-util: 29.4.3 - jest-util: 29.5.0 - micromatch: 4.0.5 - pirates: 4.0.5 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/types@29.5.0: - resolution: {integrity: sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.4.3 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.1 - '@types/node': 18.16.16 - '@types/yargs': 17.0.24 - chalk: 4.1.2 - dev: true - - /@jridgewell/gen-mapping@0.3.3: - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - - /@jridgewell/resolve-uri@3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/sourcemap-codec@1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true - - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true - - /@jridgewell/trace-mapping@0.3.18: - resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - - /@mozilla/readability@0.4.4: - resolution: {integrity: sha512-MCgZyANpJ6msfvVMi6+A0UAsvZj//4OHREYUB9f2087uXHVoU+H+SWhuihvb1beKpM323bReQPRio0WNk2+V6g==} - engines: {node: '>=14.0.0'} - dev: false - - /@mrmlnc/readdir-enhanced@2.2.1: - resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==} - engines: {node: '>=4'} - dependencies: - call-me-maybe: 1.0.2 - glob-to-regexp: 0.3.0 - dev: true - - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - /@nodelib/fs.stat@1.1.3: - resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==} - engines: {node: '>= 6'} - dev: true - - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 - - /@pkgjs/parseargs@0.11.0: - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - requiresBuild: true - dev: true - optional: true - - /@prisma/client@4.15.0(prisma@5.0.0): - resolution: {integrity: sha512-xnROvyABcGiwqRNdrObHVZkD9EjkJYHOmVdlKy1yGgI+XOzvMzJ4tRg3dz1pUlsyhKxXGCnjIQjWW+2ur+YXuw==} - engines: {node: '>=14.17'} - requiresBuild: true - peerDependencies: - prisma: '*' - peerDependenciesMeta: - prisma: - optional: true - dependencies: - '@prisma/engines-version': 4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944 - prisma: 5.0.0 - dev: false - - /@prisma/debug@4.15.0: - resolution: {integrity: sha512-dkbPz+gOVlWDBAaOEseSpAUz9NppT38UlwdryPyrwct6OClLirNC7wH+TpAQk5OZp9x59hNnfDz+T7XvL1v0/Q==} - dependencies: - '@types/debug': 4.1.8 - debug: 4.3.4 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@prisma/engines-version@4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944: - resolution: {integrity: sha512-sVOig4tjGxxlYaFcXgE71f/rtFhzyYrfyfNFUsxCIEJyVKU9rdOWIlIwQ2NQ7PntvGnn+x0XuFo4OC1jvPJKzg==} - dev: false - - /@prisma/engines@5.0.0: - resolution: {integrity: sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==} - requiresBuild: true - - /@prisma/generator-helper@4.15.0: - resolution: {integrity: sha512-JVHNgXr0LrcqXqmFrs+BzxfyRL6cFD5GLTMVWfCLU7kqSJdWuZxfoZW995tg6mOXnBgPTf6Ocv3RY4RLQq8k4g==} - dependencies: - '@prisma/debug': 4.15.0 - '@types/cross-spawn': 6.0.2 - cross-spawn: 7.0.3 - kleur: 4.1.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@sinclair/typebox@0.25.24: - resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} - dev: true - - /@sinonjs/commons@3.0.0: - resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} - dependencies: - type-detect: 4.0.8 - dev: true - - /@sinonjs/fake-timers@10.2.0: - resolution: {integrity: sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==} - dependencies: - '@sinonjs/commons': 3.0.0 - dev: true - - /@tsconfig/node10@1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true - - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - - /@tsconfig/node16@1.0.4: - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true - - /@types/babel__core@7.20.1: - resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} - dependencies: - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - '@types/babel__generator': 7.6.4 - '@types/babel__template': 7.4.1 - '@types/babel__traverse': 7.20.1 - dev: true - - /@types/babel__generator@7.6.4: - resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@types/babel__template@7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} - dependencies: - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - dev: true - - /@types/babel__traverse@7.20.1: - resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@types/bluebird@3.5.38: - resolution: {integrity: sha512-yR/Kxc0dd4FfwtEoLZMoqJbM/VE/W7hXn/MIjb+axcwag0iFmSPK7OBUZq1YWLynJUoWQkfUrI7T0HDqGApNSg==} - dev: false - - /@types/caseless@0.12.2: - resolution: {integrity: sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==} - dev: false - - /@types/cross-spawn@6.0.2: - resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} - dependencies: - '@types/node': 18.16.16 - dev: true - - /@types/debug@4.1.8: - resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} - dependencies: - '@types/ms': 0.7.31 - dev: true - - /@types/eslint-visitor-keys@1.0.0: - resolution: {integrity: sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==} - dev: false - - /@types/glob@7.2.0: - resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} - dependencies: - '@types/minimatch': 5.1.2 - '@types/node': 18.16.16 - dev: true - - /@types/graceful-fs@4.1.6: - resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} - dependencies: - '@types/node': 18.16.16 - dev: true - - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} - dev: true - - /@types/istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} - dependencies: - '@types/istanbul-lib-coverage': 2.0.4 - dev: true - - /@types/istanbul-reports@3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} - dependencies: - '@types/istanbul-lib-report': 3.0.0 - dev: true - - /@types/jest@29.5.2: - resolution: {integrity: sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==} - dependencies: - expect: 29.5.0 - pretty-format: 29.5.0 - dev: true - - /@types/json-schema@7.0.12: - resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} - - /@types/minimatch@5.1.2: - resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} - dev: true - - /@types/ms@0.7.31: - resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} - dev: true - - /@types/node@18.16.16: - resolution: {integrity: sha512-NpaM49IGQQAUlBhHMF82QH80J08os4ZmyF9MkpCzWAGuOHqE4gTEbhzd7L3l5LmWuZ6E0OiC1FweQ4tsiW35+g==} - - /@types/prettier@2.7.3: - resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} - dev: true - - /@types/request-promise@4.1.48: - resolution: {integrity: sha512-sLsfxfwP5G3E3U64QXxKwA6ctsxZ7uKyl4I28pMj3JvV+ztWECRns73GL71KMOOJME5u1A5Vs5dkBqyiR1Zcnw==} - dependencies: - '@types/bluebird': 3.5.38 - '@types/request': 2.48.8 - dev: false - - /@types/request@2.48.8: - resolution: {integrity: sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==} - dependencies: - '@types/caseless': 0.12.2 - '@types/node': 18.16.16 - '@types/tough-cookie': 4.0.2 - form-data: 2.5.1 - dev: false - - /@types/semver@7.5.0: - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} - dev: true - - /@types/stack-utils@2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - dev: true - - /@types/tough-cookie@4.0.2: - resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} - dev: false - - /@types/yargs-parser@21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} - dev: true - - /@types/yargs@17.0.24: - resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} - dependencies: - '@types/yargs-parser': 21.0.0 - dev: true - - /@typescript-eslint/eslint-plugin@2.34.0(@typescript-eslint/parser@2.34.0)(eslint@6.8.0)(typescript@3.9.10): - resolution: {integrity: sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - '@typescript-eslint/parser': ^2.0.0 - eslint: ^5.0.0 || ^6.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/experimental-utils': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/parser': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - eslint: 6.8.0 - functional-red-black-tree: 1.0.1 - regexpp: 3.2.0 - tsutils: 3.21.0(typescript@3.9.10) - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/eslint-plugin@5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.45.0)(typescript@4.9.5): - resolution: {integrity: sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 5.59.8(eslint@8.45.0)(typescript@4.9.5) - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/type-utils': 5.59.8(eslint@8.45.0)(typescript@4.9.5) - '@typescript-eslint/utils': 5.59.8(eslint@8.45.0)(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.45.0 - grapheme-splitter: 1.0.4 - ignore: 5.2.4 - natural-compare-lite: 1.4.0 - semver: 7.5.1 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/experimental-utils@2.34.0(eslint@6.8.0)(typescript@3.9.10): - resolution: {integrity: sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - eslint: '*' - dependencies: - '@types/json-schema': 7.0.12 - '@typescript-eslint/typescript-estree': 2.34.0(typescript@3.9.10) - eslint: 6.8.0 - eslint-scope: 5.1.1 - eslint-utils: 2.1.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: false - - /@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10): - resolution: {integrity: sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - eslint: ^5.0.0 || ^6.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@types/eslint-visitor-keys': 1.0.0 - '@typescript-eslint/experimental-utils': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/typescript-estree': 2.34.0(typescript@3.9.10) - eslint: 6.8.0 - eslint-visitor-keys: 1.3.0 - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/parser@5.59.8(eslint@8.45.0)(typescript@4.9.5): - resolution: {integrity: sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.45.0 - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/scope-manager@5.59.8: - resolution: {integrity: sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/visitor-keys': 5.59.8 - dev: true - - /@typescript-eslint/type-utils@5.59.8(eslint@8.45.0)(typescript@4.9.5): - resolution: {integrity: sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) - '@typescript-eslint/utils': 5.59.8(eslint@8.45.0)(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.45.0 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/types@5.59.8: - resolution: {integrity: sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /@typescript-eslint/typescript-estree@2.34.0(typescript@3.9.10): - resolution: {integrity: sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - debug: 4.3.4 - eslint-visitor-keys: 1.3.0 - glob: 7.2.3 - is-glob: 4.0.3 - lodash: 4.17.21 - semver: 7.5.1 - tsutils: 3.21.0(typescript@3.9.10) - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/typescript-estree@5.59.8(typescript@4.9.5): - resolution: {integrity: sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/visitor-keys': 5.59.8 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.1 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/utils@5.59.8(eslint@8.45.0)(typescript@4.9.5): - resolution: {integrity: sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) - '@types/json-schema': 7.0.12 - '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) - eslint: 8.45.0 - eslint-scope: 5.1.1 - semver: 7.5.1 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/visitor-keys@5.59.8: - resolution: {integrity: sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.59.8 - eslint-visitor-keys: 3.4.1 - dev: true - - /accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - dev: false - - /acorn-jsx@5.3.2(acorn@7.4.1): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 7.4.1 - dev: false - - /acorn-jsx@5.3.2(acorn@8.10.0): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.10.0 - - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn@7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: false - - /acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} - engines: {node: '>=0.4.0'} - hasBin: true - - /acorn@8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - /ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - - /ansi-regex@4.1.1: - resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} - engines: {node: '>=6'} - dev: false - - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - /ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - dev: true - - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - - /ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - dev: true - - /ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - dev: true - - /anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - dev: true - - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - /arr-diff@4.0.0: - resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} - engines: {node: '>=0.10.0'} - dev: true - - /arr-flatten@1.1.0: - resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} - engines: {node: '>=0.10.0'} - dev: true - - /arr-union@3.1.0: - resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} - engines: {node: '>=0.10.0'} - dev: true - - /array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - dev: false - - /array-union@1.0.2: - resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} - engines: {node: '>=0.10.0'} - dependencies: - array-uniq: 1.0.3 - dev: true - - /array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true - - /array-uniq@1.0.3: - resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} - engines: {node: '>=0.10.0'} - dev: true - - /array-unique@0.3.2: - resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} - engines: {node: '>=0.10.0'} - dev: true - - /asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - dependencies: - safer-buffer: 2.1.2 - dev: false - - /assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - dev: false - - /assign-symbols@1.0.0: - resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} - engines: {node: '>=0.10.0'} - dev: true - - /astral-regex@1.0.0: - resolution: {integrity: sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==} - engines: {node: '>=4'} - dev: false - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - - /atob@2.1.2: - resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} - engines: {node: '>= 4.5.0'} - hasBin: true - dev: true - - /aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - dev: false - - /aws4@1.12.0: - resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} - dev: false - - /babel-jest@29.5.0(@babel/core@7.22.1): - resolution: {integrity: sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - dependencies: - '@babel/core': 7.22.1 - '@jest/transform': 29.5.0 - '@types/babel__core': 7.20.1 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.5.0(@babel/core@7.22.1) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - dependencies: - '@babel/helper-plugin-utils': 7.21.5 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-jest-hoist@29.5.0: - resolution: {integrity: sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/template': 7.21.9 - '@babel/types': 7.22.4 - '@types/babel__core': 7.20.1 - '@types/babel__traverse': 7.20.1 - dev: true - - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.1): - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.1 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.1) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.1) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.1) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.1) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.1) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.1) - dev: true - - /babel-preset-jest@29.5.0(@babel/core@7.22.1): - resolution: {integrity: sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.1 - babel-plugin-jest-hoist: 29.5.0 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.1) - dev: true - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: false - - /base@0.11.2: - resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} - engines: {node: '>=0.10.0'} - dependencies: - cache-base: 1.0.1 - class-utils: 0.3.6 - component-emitter: 1.3.0 - define-property: 1.0.0 - isobject: 3.0.1 - mixin-deep: 1.3.2 - pascalcase: 0.1.1 - dev: true - - /bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - dependencies: - tweetnacl: 0.14.5 - dev: false - - /bellajs@11.1.2: - resolution: {integrity: sha512-2Fy3Km5JKyIy/KunW3oica2gZtkjD2qSqti2Q3xPhHvXXdMbc+32pEMOPG+xrSat0BXVhRjHIx++lzxIPK0GqQ==} - engines: {node: '>= 14'} - dev: false - - /bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - dev: false - - /body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.1 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: false - - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - - /braces@2.3.2: - resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} - engines: {node: '>=0.10.0'} - dependencies: - arr-flatten: 1.1.0 - array-unique: 0.3.2 - extend-shallow: 2.0.1 - fill-range: 4.0.0 - isobject: 3.0.1 - repeat-element: 1.1.4 - snapdragon: 0.8.2 - snapdragon-node: 2.1.1 - split-string: 3.1.0 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - - /brotli@1.3.3: - resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} - dependencies: - base64-js: 1.5.1 - dev: false - - /browserslist@4.21.7: - resolution: {integrity: sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001494 - electron-to-chromium: 1.4.419 - node-releases: 2.0.12 - update-browserslist-db: 1.0.11(browserslist@4.21.7) - dev: true - - /bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} - dependencies: - fast-json-stable-stringify: 2.1.0 - dev: true - - /bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - dependencies: - node-int64: 0.4.0 - dev: true - - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - dev: false - - /cache-base@1.0.1: - resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} - engines: {node: '>=0.10.0'} - dependencies: - collection-visit: 1.0.0 - component-emitter: 1.3.0 - get-value: 2.0.6 - has-value: 1.0.0 - isobject: 3.0.1 - set-value: 2.0.1 - to-object-path: 0.3.0 - union-value: 1.0.1 - unset-value: 1.0.0 - dev: true - - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 - dev: false - - /call-me-maybe@1.0.2: - resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - dev: true - - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: true - - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - dev: true - - /caniuse-lite@1.0.30001494: - resolution: {integrity: sha512-sY2B5Qyl46ZzfYDegrl8GBCzdawSLT4ThM9b9F+aDYUrAG2zCOyMbd2Tq34mS1g4ZKBfjRlzOohQMxx28x6wJg==} - dev: true - - /caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - dev: false - - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - /char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - dev: true - - /chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: false - - /cheerio-select@2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - dependencies: - boolbase: 1.0.0 - css-select: 5.1.0 - css-what: 6.1.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - dev: false - - /cheerio@1.0.0-rc.12: - resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} - engines: {node: '>= 6'} - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.1.0 - htmlparser2: 8.0.2 - parse5: 7.1.2 - parse5-htmlparser2-tree-adapter: 7.0.0 - dev: false - - /ci-info@3.8.0: - resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} - engines: {node: '>=8'} - dev: true - - /cjs-module-lexer@1.2.2: - resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} - dev: true - - /class-utils@0.3.6: - resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - define-property: 0.2.5 - isobject: 3.0.1 - static-extend: 0.1.2 - dev: true - - /cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: false - - /cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} - dev: false - - /cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /cloudscraper-ts@1.0.9: - resolution: {integrity: sha512-aPJC1pOI9xfceelvDonKg2bueH3wbuKMSEk40mnIAoXftv1Ut0d1qI4fu9w2UUCnbwUb6TJIm9jk6zzvkC4BWg==} - dependencies: - '@types/request-promise': 4.1.48 - '@typescript-eslint/eslint-plugin': 2.34.0(@typescript-eslint/parser@2.34.0)(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/parser': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - brotli: 1.3.3 - es6-symbol: 3.1.3 - eslint: 6.8.0 - request: 2.88.2 - request-promise: 4.2.6(request@2.88.2) - request-promise-core: 1.1.4(request@2.88.2) - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: false - - /cluster-key-slot@1.1.2: - resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} - engines: {node: '>=0.10.0'} - dev: false - - /co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: true - - /collect-v8-coverage@1.0.1: - resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} - dev: true - - /collection-visit@1.0.0: - resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} - engines: {node: '>=0.10.0'} - dependencies: - map-visit: 1.0.0 - object-visit: 1.0.1 - dev: true - - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - /colors@1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} - dev: false - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true - - /complex.js@2.1.1: - resolution: {integrity: sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==} - dev: false - - /component-emitter@1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} - dev: true - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - /content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - dev: false - - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true - - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true - - /cookie-parser@1.4.6: - resolution: {integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==} - engines: {node: '>= 0.8.0'} - dependencies: - cookie: 0.4.1 - cookie-signature: 1.0.6 - dev: false - - /cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - dev: false - - /cookie@0.4.1: - resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==} - engines: {node: '>= 0.6'} - dev: false - - /cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - dev: false - - /copy-descriptor@0.1.1: - resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} - engines: {node: '>=0.10.0'} - dev: true - - /copyfiles@2.4.1: - resolution: {integrity: sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==} - hasBin: true - dependencies: - glob: 7.2.3 - minimatch: 3.1.2 - mkdirp: 1.0.4 - noms: 0.0.0 - through2: 2.0.5 - untildify: 4.0.0 - yargs: 16.2.0 - dev: true - - /core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - dev: false - - /core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: true - - /cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - dev: false - - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - - /cross-fetch@3.1.6: - resolution: {integrity: sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==} - dependencies: - node-fetch: 2.6.11 - transitivePeerDependencies: - - encoding - dev: false - - /cross-spawn@6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.2 - shebang-command: 1.2.0 - which: 1.3.1 - dev: false - - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - /crypto-js@4.1.1: - resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} - dev: false - - /css-select@5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} - dependencies: - boolbase: 1.0.0 - css-what: 6.1.0 - domhandler: 5.0.3 - domutils: 3.1.0 - nth-check: 2.1.1 - dev: false - - /css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} - engines: {node: '>= 6'} - dev: false - - /cssom@0.5.0: - resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - dev: false - - /d@1.0.1: - resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} - dependencies: - es5-ext: 0.10.62 - type: 1.2.0 - dev: false - - /dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - dependencies: - assert-plus: 1.0.0 - dev: false - - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - - /decimal.js@10.4.3: - resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - dev: false - - /decode-uri-component@0.2.2: - resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} - engines: {node: '>=0.10'} - dev: true - - /dedent@0.7.0: - resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dev: true - - /deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - /deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - - /define-property@0.2.5: - resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 0.1.6 - dev: true - - /define-property@1.0.0: - resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - dev: true - - /define-property@2.0.2: - resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - isobject: 3.0.1 - dev: true - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - - /denque@2.1.0: - resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} - engines: {node: '>=0.10'} - dev: false - - /depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - dev: false - - /destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dev: false - - /detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - dev: true - - /diff-sequences@29.4.3: - resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true - - /dir-glob@2.2.2: - resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==} - engines: {node: '>=4'} - dependencies: - path-type: 3.0.0 - dev: true - - /dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - - /doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - - /dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - dev: false - - /domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: false - - /domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: false - - /domutils@3.1.0: - resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - dev: false - - /dotenv@16.1.4: - resolution: {integrity: sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==} - engines: {node: '>=12'} - dev: false - - /eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - dev: true - - /ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - dev: false - - /ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - dev: false - - /electron-to-chromium@1.4.419: - resolution: {integrity: sha512-jdie3RiEgygvDTyS2sgjq71B36q2cDSBfPlwzUyuOrfYTNoYWyBxxjGJV/HAu3A2hB0Y+HesvCVkVAFoCKwCSw==} - dev: true - - /emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - dev: true - - /emoji-regex@7.0.3: - resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} - dev: false - - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - /emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true - - /encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - dev: false - - /entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - dev: false - - /error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - - /es5-ext@0.10.62: - resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} - engines: {node: '>=0.10'} - requiresBuild: true - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.3 - next-tick: 1.1.0 - dev: false - - /es6-iterator@2.0.3: - resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} - dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - es6-symbol: 3.1.3 - dev: false - - /es6-symbol@3.1.3: - resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} - dependencies: - d: 1.0.1 - ext: 1.7.0 - dev: false - - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - dev: true - - /escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - dev: false - - /escape-latex@1.2.0: - resolution: {integrity: sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==} - dev: false - - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - /escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true - - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - /eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - /eslint-scope@7.2.0: - resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - /eslint-utils@1.4.3: - resolution: {integrity: sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==} - engines: {node: '>=6'} - dependencies: - eslint-visitor-keys: 1.3.0 - dev: false - - /eslint-utils@2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - dependencies: - eslint-visitor-keys: 1.3.0 - dev: false - - /eslint-visitor-keys@1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} - dev: false - - /eslint-visitor-keys@3.4.1: - resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - /eslint@6.8.0: - resolution: {integrity: sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - hasBin: true - dependencies: - '@babel/code-frame': 7.21.4 - ajv: 6.12.6 - chalk: 2.4.2 - cross-spawn: 6.0.5 - debug: 4.3.4 - doctrine: 3.0.0 - eslint-scope: 5.1.1 - eslint-utils: 1.4.3 - eslint-visitor-keys: 1.3.0 - espree: 6.2.1 - esquery: 1.5.0 - esutils: 2.0.3 - file-entry-cache: 5.0.1 - functional-red-black-tree: 1.0.1 - glob-parent: 5.1.2 - globals: 12.4.0 - ignore: 4.0.6 - import-fresh: 3.3.0 - imurmurhash: 0.1.4 - inquirer: 7.3.3 - is-glob: 4.0.3 - js-yaml: 3.14.1 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.3.0 - lodash: 4.17.21 - minimatch: 3.1.2 - mkdirp: 0.5.6 - natural-compare: 1.4.0 - optionator: 0.8.3 - progress: 2.0.3 - regexpp: 2.0.1 - semver: 6.3.0 - strip-ansi: 5.2.0 - strip-json-comments: 3.1.1 - table: 5.4.6 - text-table: 0.2.0 - v8-compile-cache: 2.3.0 - transitivePeerDependencies: - - supports-color - dev: false - - /eslint@8.45.0: - resolution: {integrity: sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) - '@eslint-community/regexpp': 4.5.1 - '@eslint/eslintrc': 2.1.0 - '@eslint/js': 8.44.0 - '@humanwhocodes/config-array': 0.11.10 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.0 - eslint-visitor-keys: 3.4.1 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.20.0 - graphemer: 1.4.0 - ignore: 5.2.4 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - /espree@6.2.1: - resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} - engines: {node: '>=6.0.0'} - dependencies: - acorn: 7.4.1 - acorn-jsx: 5.3.2(acorn@7.4.1) - eslint-visitor-keys: 1.3.0 - dev: false - - /espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) - eslint-visitor-keys: 3.4.1 - - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - /esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - - /esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - dependencies: - estraverse: 5.3.0 - - /estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - - /estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - /etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - dev: false - - /eventemitter2@6.4.9: - resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} - dev: false - - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - dev: true - - /expand-brackets@2.1.4: - resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} - engines: {node: '>=0.10.0'} - dependencies: - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - posix-character-classes: 0.1.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /expect@29.5.0: - resolution: {integrity: sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/expect-utils': 29.5.0 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - dev: true - - /express-domain-middleware@0.1.0: - resolution: {integrity: sha512-k6UitrDPN0NbTJutuG671/wQXWFyjSbkYdKtDRHxz0VuZA1cLTMkbUIGMkmHwgQwE/XhrQyK7ZjzCFRFlaD4xw==} - dev: false - - /express-rate-limit@6.7.0(express@4.18.2): - resolution: {integrity: sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==} - engines: {node: '>= 12.9.0'} - peerDependencies: - express: ^4 || ^5 - dependencies: - express: 4.18.2 - dev: false - - /express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} - engines: {node: '>= 0.10.0'} - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.1 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.5.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.7 - qs: 6.11.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /ext@1.7.0: - resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} - dependencies: - type: 2.7.2 - dev: false - - /extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - dev: true - - /extend-shallow@3.0.2: - resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} - engines: {node: '>=0.10.0'} - dependencies: - assign-symbols: 1.0.0 - is-extendable: 1.0.1 - dev: true - - /extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: false - - /external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: false - - /extglob@2.0.4: - resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} - engines: {node: '>=0.10.0'} - dependencies: - array-unique: 0.3.2 - define-property: 1.0.0 - expand-brackets: 2.1.4 - extend-shallow: 2.0.1 - fragment-cache: 0.2.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - dev: false - - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - /fast-glob@2.2.7: - resolution: {integrity: sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==} - engines: {node: '>=4.0.0'} - dependencies: - '@mrmlnc/readdir-enhanced': 2.2.1 - '@nodelib/fs.stat': 1.1.3 - glob-parent: 3.1.0 - is-glob: 4.0.3 - merge2: 1.4.1 - micromatch: 3.1.10 - transitivePeerDependencies: - - supports-color - dev: true - - /fast-glob@3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - /fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - /fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - dependencies: - reusify: 1.0.4 - - /fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - dependencies: - bser: 2.1.1 - dev: true - - /figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - dependencies: - escape-string-regexp: 1.0.5 - dev: false - - /file-entry-cache@5.0.1: - resolution: {integrity: sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==} - engines: {node: '>=4'} - dependencies: - flat-cache: 2.0.1 - dev: false - - /file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.0.4 - - /fill-range@4.0.0: - resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-number: 3.0.0 - repeat-string: 1.6.1 - to-regex-range: 2.1.1 - dev: true - - /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - - /finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} - dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true - - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - /flat-cache@2.0.1: - resolution: {integrity: sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==} - engines: {node: '>=4'} - dependencies: - flatted: 2.0.2 - rimraf: 2.6.3 - write: 1.0.3 - dev: false - - /flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 - - /flatted@2.0.2: - resolution: {integrity: sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==} - dev: false - - /flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - - /for-in@1.0.2: - resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} - engines: {node: '>=0.10.0'} - dev: true - - /foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.0.2 - dev: true - - /forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - dev: false - - /form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /form-data@2.5.1: - resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - dev: false - - /fraction.js@4.2.0: - resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} - dev: false - - /fragment-cache@0.2.1: - resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} - engines: {node: '>=0.10.0'} - dependencies: - map-cache: 0.2.2 - dev: true - - /fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - dev: false - - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - - /functional-red-black-tree@1.0.1: - resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} - dev: false - - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-proto: 1.0.1 - has-symbols: 1.0.3 - dev: false - - /get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true - - /get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - dev: true - - /get-value@2.0.6: - resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} - engines: {node: '>=0.10.0'} - dev: true - - /getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - dependencies: - assert-plus: 1.0.0 - dev: false - - /glob-parent@3.1.0: - resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} - dependencies: - is-glob: 3.1.0 - path-dirname: 1.0.2 - dev: true - - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - - /glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - dependencies: - is-glob: 4.0.3 - - /glob-to-regexp@0.3.0: - resolution: {integrity: sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==} - dev: true - - /glob@10.2.6: - resolution: {integrity: sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.2.1 - minimatch: 9.0.1 - minipass: 6.0.2 - path-scurry: 1.9.2 - dev: true - - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - /globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true - - /globals@12.4.0: - resolution: {integrity: sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.8.1 - dev: false - - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - - /globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.2.12 - ignore: 5.2.4 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - - /globby@9.2.0: - resolution: {integrity: sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==} - engines: {node: '>=6'} - dependencies: - '@types/glob': 7.2.0 - array-union: 1.0.2 - dir-glob: 2.2.2 - fast-glob: 2.2.7 - glob: 7.2.3 - ignore: 4.0.6 - pify: 4.0.1 - slash: 2.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true - - /grapheme-splitter@1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} - dev: true - - /graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - /har-schema@2.0.0: - resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} - engines: {node: '>=4'} - dev: false - - /har-validator@5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported - dependencies: - ajv: 6.12.6 - har-schema: 2.0.0 - dev: false - - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - dev: false - - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - dev: false - - /has-value@0.3.1: - resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 0.1.4 - isobject: 2.1.0 - dev: true - - /has-value@1.0.0: - resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 1.0.0 - isobject: 3.0.1 - dev: true - - /has-values@0.1.4: - resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} - engines: {node: '>=0.10.0'} - dev: true - - /has-values@1.0.0: - resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - kind-of: 4.0.0 - dev: true - - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true - - /html-escaper@3.0.3: - resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} - dev: false - - /htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - entities: 4.5.0 - dev: false - - /http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - dev: false - - /http-signature@1.2.0: - resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} - engines: {node: '>=0.8', npm: '>=1.3.7'} - dependencies: - assert-plus: 1.0.0 - jsprim: 1.4.2 - sshpk: 1.17.0 - dev: false - - /human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true - - /iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: false - - /ignore@4.0.6: - resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} - engines: {node: '>= 4'} - - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} - engines: {node: '>= 4'} - - /import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - /import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - dev: true - - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - /inquirer@7.3.3: - resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} - engines: {node: '>=8.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - run-async: 2.4.1 - rxjs: 6.6.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - dev: false - - /ioredis@5.3.2: - resolution: {integrity: sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==} - engines: {node: '>=12.22.0'} - dependencies: - '@ioredis/commands': 1.2.0 - cluster-key-slot: 1.1.2 - debug: 4.3.4 - denque: 2.1.0 - lodash.defaults: 4.2.0 - lodash.isarguments: 3.1.0 - redis-errors: 1.2.0 - redis-parser: 3.0.0 - standard-as-callback: 2.1.0 - transitivePeerDependencies: - - supports-color - dev: false - - /ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - dev: false - - /is-accessor-descriptor@0.1.6: - resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-accessor-descriptor@1.0.0: - resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - - /is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true - - /is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: true - - /is-core-module@2.12.1: - resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} - dependencies: - has: 1.0.3 - dev: true - - /is-data-descriptor@0.1.4: - resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-data-descriptor@1.0.0: - resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - - /is-descriptor@0.1.6: - resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 0.1.6 - is-data-descriptor: 0.1.4 - kind-of: 5.1.0 - dev: true - - /is-descriptor@1.0.2: - resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 1.0.0 - is-data-descriptor: 1.0.0 - kind-of: 6.0.3 - dev: true - - /is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - dev: true - - /is-extendable@1.0.1: - resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} - engines: {node: '>=0.10.0'} - dependencies: - is-plain-object: 2.0.4 - dev: true - - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - /is-fullwidth-code-point@2.0.0: - resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} - engines: {node: '>=4'} - dev: false - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - /is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - dev: true - - /is-glob@3.1.0: - resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - - /is-number@3.0.0: - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true - - /is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - /is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - dev: false - - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true - - /is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: false - - /is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - dev: true - - /isarray@0.0.1: - resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} - dev: true - - /isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: true - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - /isobject@2.1.0: - resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} - engines: {node: '>=0.10.0'} - dependencies: - isarray: 1.0.0 - dev: true - - /isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - dev: true - - /isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - dev: false - - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} - engines: {node: '>=8'} - dev: true - - /istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - dependencies: - '@babel/core': 7.22.1 - '@babel/parser': 7.22.4 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} - engines: {node: '>=8'} - dependencies: - istanbul-lib-coverage: 3.2.0 - make-dir: 3.1.0 - supports-color: 7.2.0 - dev: true - - /istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - dependencies: - debug: 4.3.4 - istanbul-lib-coverage: 3.2.0 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-reports@3.1.5: - resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} - engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.0 - dev: true - - /jackspeak@2.2.1: - resolution: {integrity: sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==} - engines: {node: '>=14'} - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - dev: true - - /javascript-natural-sort@0.7.1: - resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} - dev: false - - /jest-changed-files@29.5.0: - resolution: {integrity: sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - execa: 5.1.1 - p-limit: 3.1.0 - dev: true - - /jest-circus@29.5.0: - resolution: {integrity: sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.5.0 - '@jest/expect': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - co: 4.6.0 - dedent: 0.7.0 - is-generator-fn: 2.1.0 - jest-each: 29.5.0 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-runtime: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 - p-limit: 3.1.0 - pretty-format: 29.5.0 - pure-rand: 6.0.2 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-cli@29.5.0(@types/node@18.16.16)(ts-node@10.9.1): - resolution: {integrity: sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.5.0(ts-node@10.9.1) - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - import-local: 3.1.0 - jest-config: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - jest-util: 29.5.0 - jest-validate: 29.5.0 - prompts: 2.4.2 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /jest-config@29.5.0(@types/node@18.16.16)(ts-node@10.9.1): - resolution: {integrity: sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==} - 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 - dependencies: - '@babel/core': 7.22.1 - '@jest/test-sequencer': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - babel-jest: 29.5.0(@babel/core@7.22.1) - chalk: 4.1.2 - ci-info: 3.8.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.5.0 - jest-environment-node: 29.5.0 - jest-get-type: 29.4.3 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-runner: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.5.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - ts-node: 10.9.1(@types/node@18.16.16)(typescript@4.9.5) - transitivePeerDependencies: - - supports-color - dev: true - - /jest-diff@29.5.0: - resolution: {integrity: sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - diff-sequences: 29.4.3 - jest-get-type: 29.4.3 - pretty-format: 29.5.0 - dev: true - - /jest-docblock@29.4.3: - resolution: {integrity: sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - detect-newline: 3.1.0 - dev: true - - /jest-each@29.5.0: - resolution: {integrity: sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - chalk: 4.1.2 - jest-get-type: 29.4.3 - jest-util: 29.5.0 - pretty-format: 29.5.0 - dev: true - - /jest-environment-node@29.5.0: - resolution: {integrity: sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.5.0 - '@jest/fake-timers': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - jest-mock: 29.5.0 - jest-util: 29.5.0 - dev: true - - /jest-get-type@29.4.3: - resolution: {integrity: sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - - /jest-haste-map@29.5.0: - resolution: {integrity: sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@types/graceful-fs': 4.1.6 - '@types/node': 18.16.16 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 29.4.3 - jest-util: 29.5.0 - jest-worker: 29.5.0 - micromatch: 4.0.5 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /jest-leak-detector@29.5.0: - resolution: {integrity: sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.4.3 - pretty-format: 29.5.0 - dev: true - - /jest-matcher-utils@29.5.0: - resolution: {integrity: sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - jest-diff: 29.5.0 - jest-get-type: 29.4.3 - pretty-format: 29.5.0 - dev: true - - /jest-message-util@29.5.0: - resolution: {integrity: sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/code-frame': 7.21.4 - '@jest/types': 29.5.0 - '@types/stack-utils': 2.0.1 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.5 - pretty-format: 29.5.0 - slash: 3.0.0 - stack-utils: 2.0.6 - dev: true - - /jest-mock@29.5.0: - resolution: {integrity: sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - jest-util: 29.5.0 - dev: true - - /jest-pnp-resolver@1.2.3(jest-resolve@29.5.0): - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - dependencies: - jest-resolve: 29.5.0 - dev: true - - /jest-regex-util@29.4.3: - resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - - /jest-resolve-dependencies@29.5.0: - resolution: {integrity: sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-regex-util: 29.4.3 - jest-snapshot: 29.5.0 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-resolve@29.5.0: - resolution: {integrity: sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.5.0) - jest-util: 29.5.0 - jest-validate: 29.5.0 - resolve: 1.22.2 - resolve.exports: 2.0.2 - slash: 3.0.0 - dev: true - - /jest-runner@29.5.0: - resolution: {integrity: sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.5.0 - '@jest/environment': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.4.3 - jest-environment-node: 29.5.0 - jest-haste-map: 29.5.0 - jest-leak-detector: 29.5.0 - jest-message-util: 29.5.0 - jest-resolve: 29.5.0 - jest-runtime: 29.5.0 - jest-util: 29.5.0 - jest-watcher: 29.5.0 - jest-worker: 29.5.0 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-runtime@29.5.0: - resolution: {integrity: sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.5.0 - '@jest/fake-timers': 29.5.0 - '@jest/globals': 29.5.0 - '@jest/source-map': 29.4.3 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - cjs-module-lexer: 1.2.2 - collect-v8-coverage: 1.0.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - jest-message-util: 29.5.0 - jest-mock: 29.5.0 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-snapshot@29.5.0: - resolution: {integrity: sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.22.1 - '@babel/generator': 7.22.3 - '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.22.1) - '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.22.1) - '@babel/traverse': 7.22.4 - '@babel/types': 7.22.4 - '@jest/expect-utils': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/babel__traverse': 7.20.1 - '@types/prettier': 2.7.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.1) - chalk: 4.1.2 - expect: 29.5.0 - graceful-fs: 4.2.11 - jest-diff: 29.5.0 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - natural-compare: 1.4.0 - pretty-format: 29.5.0 - semver: 7.5.1 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-util@29.5.0: - resolution: {integrity: sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - ci-info: 3.8.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - dev: true - - /jest-validate@29.5.0: - resolution: {integrity: sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.4.3 - leven: 3.1.0 - pretty-format: 29.5.0 - dev: true - - /jest-watcher@29.5.0: - resolution: {integrity: sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.5.0 - string-length: 4.0.2 - dev: true - - /jest-worker@29.5.0: - resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@types/node': 18.16.16 - jest-util: 29.5.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 - dev: true - - /jest@29.5.0(@types/node@18.16.16)(ts-node@10.9.1): - resolution: {integrity: sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.5.0(ts-node@10.9.1) - '@jest/types': 29.5.0 - import-local: 3.1.0 - jest-cli: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - - /jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - dev: false - - /jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true - - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - /json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - dev: false - - /json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - /json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: false - - /json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true - - /jsprim@1.4.2: - resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} - engines: {node: '>=0.6.0'} - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - dev: false - - /kind-of@3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of@4.0.0: - resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of@5.1.0: - resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} - engines: {node: '>=0.10.0'} - dev: true - - /kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - dev: true - - /kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true - - /kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - dev: true - - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true - - /levn@0.3.0: - resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - type-check: 0.3.2 - dev: false - - /levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - /lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true - - /linkedom@0.14.26: - resolution: {integrity: sha512-mK6TrydfFA7phrnp+1j57ycBwFI5bGSW6YXlw9acHoqF+mP/y+FooEYYyniOt5Ot57FSKB3iwmnuQ1UUyNLm5A==} - dependencies: - css-select: 5.1.0 - cssom: 0.5.0 - html-escaper: 3.0.3 - htmlparser2: 8.0.2 - uhyphen: 0.2.0 - dev: false - - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true - - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - dependencies: - p-locate: 5.0.0 - - /lodash.defaults@4.2.0: - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - dev: false - - /lodash.isarguments@3.1.0: - resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} - dev: false - - /lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - dev: true - - /lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false - - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 - dev: true - - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - - /lru-cache@9.1.2: - resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==} - engines: {node: 14 || >=16.14} - dev: true - - /make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - dependencies: - semver: 6.3.0 - dev: true - - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true - - /makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - dependencies: - tmpl: 1.0.5 - dev: true - - /map-cache@0.2.2: - resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} - engines: {node: '>=0.10.0'} - dev: true - - /map-visit@1.0.0: - resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} - engines: {node: '>=0.10.0'} - dependencies: - object-visit: 1.0.1 - dev: true - - /mathjs@11.8.0: - resolution: {integrity: sha512-I7r8HCoqUGyEiHQdeOCF2m2k9N+tcOHO3cZQ3tyJkMMBQMFqMR7dMQEboBMJAiFW2Um3PEItGPwcOc4P6KRqwg==} - engines: {node: '>= 14'} - hasBin: true - dependencies: - '@babel/runtime': 7.22.3 - complex.js: 2.1.1 - decimal.js: 10.4.3 - escape-latex: 1.2.0 - fraction.js: 4.2.0 - javascript-natural-sort: 0.7.1 - seedrandom: 3.0.5 - tiny-emitter: 2.1.0 - typed-function: 4.1.0 - dev: false - - /media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - dev: false - - /merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - dev: false - - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true - - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true - - /methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - dev: false - - /micromatch@3.1.10: - resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - braces: 2.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - extglob: 2.0.4 - fragment-cache: 0.2.1 - kind-of: 6.0.3 - nanomatch: 1.2.13 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - dev: false - - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - - /minimatch@9.0.1: - resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: true - - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - /minipass@6.0.2: - resolution: {integrity: sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==} - engines: {node: '>=16 || 14 >=14.17'} - dev: true - - /mixin-deep@1.3.2: - resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 1.0.2 - is-extendable: 1.0.1 - dev: true - - /mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - dependencies: - minimist: 1.2.8 - dev: false - - /mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: true - - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: false - - /mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: false - - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: false - - /nanomatch@1.2.13: - resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} - engines: {node: '>=0.10.0'} - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - fragment-cache: 0.2.1 - is-windows: 1.0.2 - kind-of: 6.0.3 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true - - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - /negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - dev: false - - /next-tick@1.1.0: - resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - dev: false - - /nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: false - - /node-fetch@2.6.11: - resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: false - - /node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: true - - /node-releases@2.0.12: - resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} - dev: true - - /noms@0.0.0: - resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} - dependencies: - inherits: 2.0.4 - readable-stream: 1.0.34 - dev: true - - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true - - /npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - dependencies: - path-key: 3.1.1 - dev: true - - /nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - dependencies: - boolbase: 1.0.0 - dev: false - - /oauth-sign@0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - dev: false - - /object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: false - - /object-copy@0.1.0: - resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} - engines: {node: '>=0.10.0'} - dependencies: - copy-descriptor: 0.1.1 - define-property: 0.2.5 - kind-of: 3.2.2 - dev: true - - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} - dev: false - - /object-visit@1.0.1: - resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /object.pick@1.3.0: - resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - dev: false - - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - - /optionator@0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.3.0 - prelude-ls: 1.1.2 - type-check: 0.3.2 - word-wrap: 1.2.4 - dev: false - - /optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} - dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - - /os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - dev: false - - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true - - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - dependencies: - p-limit: 3.1.0 - - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true - - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - dependencies: - callsites: 3.1.0 - - /parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - dependencies: - '@babel/code-frame': 7.21.4 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - dev: true - - /parse-srcset@1.0.2: - resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} - dev: false - - /parse5-htmlparser2-tree-adapter@7.0.0: - resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} - dependencies: - domhandler: 5.0.3 - parse5: 7.1.2 - dev: false - - /parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} - dependencies: - entities: 4.5.0 - dev: false - - /parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - dev: false - - /pascalcase@0.1.1: - resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} - engines: {node: '>=0.10.0'} - dev: true - - /path-dirname@1.0.2: - resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} - dev: true - - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - /path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - dev: false - - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true - - /path-scurry@1.9.2: - resolution: {integrity: sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - lru-cache: 9.1.2 - minipass: 6.0.2 - dev: true - - /path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - dev: false - - /path-type@3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} - dependencies: - pify: 3.0.0 - dev: true - - /path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true - - /performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - dev: false - - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true - - /pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - dev: true - - /pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - dev: true - - /pirates@4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} - engines: {node: '>= 6'} - dev: true - - /pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - dev: true - - /posix-character-classes@0.1.1: - resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} - engines: {node: '>=0.10.0'} - dev: true - - /postcss@8.4.24: - resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.6 - picocolors: 1.0.0 - source-map-js: 1.0.2 - dev: false - - /prelude-ls@1.1.2: - resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} - engines: {node: '>= 0.8.0'} - dev: false - - /prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - /prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true - - /pretty-format@29.5.0: - resolution: {integrity: sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.4.3 - ansi-styles: 5.2.0 - react-is: 18.2.0 - dev: true - - /prisma-json-types-generator@2.4.0: - resolution: {integrity: sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg==} - engines: {node: '>=14.0'} - hasBin: true - dependencies: - '@prisma/generator-helper': 4.15.0 - tslib: 2.5.3 - transitivePeerDependencies: - - supports-color - dev: true - - /prisma@5.0.0: - resolution: {integrity: sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA==} - engines: {node: '>=16.13'} - hasBin: true - requiresBuild: true - dependencies: - '@prisma/engines': 5.0.0 - - /process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true - - /progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - dev: false - - /prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - dev: true - - /proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - dev: false - - /psl@1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: false - - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} - engines: {node: '>=6'} - - /pure-rand@6.0.2: - resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} - dev: true - - /qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - dependencies: - side-channel: 1.0.4 - dev: false - - /qs@6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} - dev: false - - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - /range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - dev: false - - /rate-limit-redis@3.0.2(express-rate-limit@6.7.0): - resolution: {integrity: sha512-4SBK6AzIr9PKkCF4HmSDcJH2O2KKMF3fZEcsbNMXyaL5I9d6X71uOreUldFRiyrRyP+qkQrTxzJ38ZKKN+sScw==} - engines: {node: '>= 14.5.0'} - peerDependencies: - express-rate-limit: ^6 - dependencies: - express-rate-limit: 6.7.0(express@4.18.2) - dev: false - - /raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: false - - /raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: false - - /react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true - - /readable-stream@1.0.34: - resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 0.0.1 - string_decoder: 0.10.31 - dev: true - - /readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - dev: true - - /redis-errors@1.2.0: - resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} - engines: {node: '>=4'} - dev: false - - /redis-parser@3.0.0: - resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} - engines: {node: '>=4'} - dependencies: - redis-errors: 1.2.0 - dev: false - - /regenerator-runtime@0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - dev: false - - /regex-not@1.0.2: - resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 3.0.2 - safe-regex: 1.1.0 - dev: true - - /regexpp@2.0.1: - resolution: {integrity: sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==} - engines: {node: '>=6.5.0'} - dev: false - - /regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - dev: false - - /repeat-element@1.1.4: - resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} - engines: {node: '>=0.10.0'} - dev: true - - /repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - dev: true - - /request-promise-core@1.1.4(request@2.88.2): - resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==} - engines: {node: '>=0.10.0'} - peerDependencies: - request: ^2.34 - dependencies: - lodash: 4.17.21 - request: 2.88.2 - dev: false - - /request-promise@4.2.6(request@2.88.2): - resolution: {integrity: sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==} - engines: {node: '>=0.10.0'} - deprecated: request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 - peerDependencies: - request: ^2.34 - dependencies: - bluebird: 3.7.2 - request: 2.88.2 - request-promise-core: 1.1.4(request@2.88.2) - stealthy-require: 1.1.1 - tough-cookie: 2.5.0 - dev: false - - /request@2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - dependencies: - aws-sign2: 0.7.0 - aws4: 1.12.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.3 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 - dev: false - - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - dependencies: - resolve-from: 5.0.0 - dev: true - - /resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - /resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true - - /resolve-url@0.2.1: - resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} - deprecated: https://github.com/lydell/resolve-url#deprecated - dev: true - - /resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - dev: true - - /resolve@1.22.2: - resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} - hasBin: true - dependencies: - is-core-module: 2.12.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: false - - /ret@0.1.15: - resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} - engines: {node: '>=0.12'} - dev: true - - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - /rimraf@2.6.3: - resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: false - - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - - /rimraf@5.0.1: - resolution: {integrity: sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==} - engines: {node: '>=14'} - hasBin: true - dependencies: - glob: 10.2.6 - dev: true - - /run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - dev: false - - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - - /rxjs@6.6.7: - resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} - engines: {npm: '>=2.0.0'} - dependencies: - tslib: 1.14.1 - dev: false - - /safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true - - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: false - - /safe-regex@1.1.0: - resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} - dependencies: - ret: 0.1.15 - dev: true - - /safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: false - - /sanitize-html@2.10.0: - resolution: {integrity: sha512-JqdovUd81dG4k87vZt6uA6YhDfWkUGruUu/aPmXLxXi45gZExnt9Bnw/qeQU8oGf82vPyaE0vO4aH0PbobB9JQ==} - dependencies: - deepmerge: 4.3.1 - escape-string-regexp: 4.0.0 - htmlparser2: 8.0.2 - is-plain-object: 5.0.0 - parse-srcset: 1.0.2 - postcss: 8.4.24 - dev: false - - /seedrandom@3.0.5: - resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==} - dev: false - - /semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - dev: false - - /semver@6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - - /semver@7.5.1: - resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - - /send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - dev: false - - /serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} - dependencies: - encodeurl: 1.0.2 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.18.0 - transitivePeerDependencies: - - supports-color - dev: false - - /set-value@2.0.1: - resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-extendable: 0.1.1 - is-plain-object: 2.0.4 - split-string: 3.1.0 - dev: true - - /setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - dev: false - - /shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} - dependencies: - shebang-regex: 1.0.0 - dev: false - - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - - /shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - dev: false - - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 - dev: false - - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - /signal-exit@4.0.2: - resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} - engines: {node: '>=14'} - dev: true - - /sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true - - /slash@2.0.0: - resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} - engines: {node: '>=6'} - dev: true - - /slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true - - /slice-ansi@2.1.0: - resolution: {integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==} - engines: {node: '>=6'} - dependencies: - ansi-styles: 3.2.1 - astral-regex: 1.0.0 - is-fullwidth-code-point: 2.0.0 - dev: false - - /snapdragon-node@2.1.1: - resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 1.0.0 - isobject: 3.0.1 - snapdragon-util: 3.0.1 - dev: true - - /snapdragon-util@3.0.1: - resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /snapdragon@0.8.2: - resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} - engines: {node: '>=0.10.0'} - dependencies: - base: 0.11.2 - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - map-cache: 0.2.2 - source-map: 0.5.7 - source-map-resolve: 0.5.3 - use: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} - engines: {node: '>=0.10.0'} - dev: false - - /source-map-resolve@0.5.3: - resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} - deprecated: See https://github.com/lydell/source-map-resolve#deprecated - dependencies: - atob: 2.1.2 - decode-uri-component: 0.2.2 - resolve-url: 0.2.1 - source-map-url: 0.4.1 - urix: 0.1.0 - dev: true - - /source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map-url@0.4.1: - resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} - deprecated: See https://github.com/lydell/source-map-url#deprecated - dev: true - - /source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - dev: true - - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true - - /split-string@3.1.0: - resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 3.0.2 - dev: true - - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - /sshpk@1.17.0: - resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - dev: false - - /stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - dependencies: - escape-string-regexp: 2.0.0 - dev: true - - /standard-as-callback@2.1.0: - resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - dev: false - - /static-extend@0.1.2: - resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 0.2.5 - object-copy: 0.1.0 - dev: true - - /statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - dev: false - - /stealthy-require@1.1.1: - resolution: {integrity: sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==} - engines: {node: '>=0.10.0'} - dev: false - - /string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - dev: true - - /string-width@3.1.0: - resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} - engines: {node: '>=6'} - dependencies: - emoji-regex: 7.0.3 - is-fullwidth-code-point: 2.0.0 - strip-ansi: 5.2.0 - dev: false - - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - /string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - dev: true - - /string_decoder@0.10.31: - resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} - dev: true - - /string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - dependencies: - safe-buffer: 5.1.2 - dev: true - - /strip-ansi@5.2.0: - resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} - engines: {node: '>=6'} - dependencies: - ansi-regex: 4.1.1 - dev: false - - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - - /strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - dependencies: - ansi-regex: 6.0.1 - dev: true - - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true - - /strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true - - /strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true - - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - - /supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - dependencies: - has-flag: 4.0.0 - dev: true - - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true - - /table@5.4.6: - resolution: {integrity: sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==} - engines: {node: '>=6.0.0'} - dependencies: - ajv: 6.12.6 - lodash: 4.17.21 - slice-ansi: 2.1.0 - string-width: 3.1.0 - dev: false - - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - dev: true - - /text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - /through2@2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - dependencies: - readable-stream: 2.3.8 - xtend: 4.0.2 - dev: true - - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: false - - /tiny-emitter@2.1.0: - resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} - dev: false - - /tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - dev: false - - /tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: true - - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true - - /to-object-path@0.3.0: - resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /to-regex-range@2.1.1: - resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - repeat-string: 1.6.1 - dev: true - - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - - /to-regex@3.0.2: - resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 2.0.2 - extend-shallow: 3.0.2 - regex-not: 1.0.2 - safe-regex: 1.1.0 - dev: true - - /toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - dev: false - - /tough-cookie@2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} - dependencies: - psl: 1.9.0 - punycode: 2.3.0 - dev: false - - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false - - /ts-jest@29.1.0(@babel/core@7.22.1)(jest@29.5.0)(typescript@4.9.5): - resolution: {integrity: sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 - esbuild: '*' - jest: ^29.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - dependencies: - '@babel/core': 7.22.1 - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - jest: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - jest-util: 29.5.0 - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.5.1 - typescript: 4.9.5 - yargs-parser: 21.1.1 - dev: true - - /ts-node@10.9.1(@types/node@18.16.16)(typescript@4.9.5): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - 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 - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 18.16.16 - acorn: 8.8.2 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.9.5 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 - dev: true - - /tscpaths@0.0.9: - resolution: {integrity: sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w==} - hasBin: true - dependencies: - commander: 2.20.3 - globby: 9.2.0 - transitivePeerDependencies: - - supports-color - dev: true - - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - - /tslib@2.5.3: - resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} - dev: true - - /tsutils@3.21.0(typescript@3.9.10): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 3.9.10 - dev: false - - /tsutils@3.21.0(typescript@4.9.5): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 4.9.5 - dev: true - - /tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - dev: false - - /type-check@0.3.2: - resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - dev: false - - /type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - - /type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - dev: true - - /type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - - /type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - dev: false - - /type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - dev: false - - /type@1.2.0: - resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} - dev: false - - /type@2.7.2: - resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} - dev: false - - /typed-function@4.1.0: - resolution: {integrity: sha512-DGwUl6cioBW5gw2L+6SMupGwH/kZOqivy17E4nsh1JI9fKF87orMmlQx3KISQPmg3sfnOUGlwVkroosvgddrlg==} - engines: {node: '>= 14'} - dev: false - - /typescript@3.9.10: - resolution: {integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: false - - /typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true - - /uhyphen@0.2.0: - resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==} - dev: false - - /union-value@1.0.1: - resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - get-value: 2.0.6 - is-extendable: 0.1.1 - set-value: 2.0.1 - dev: true - - /unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - dev: false - - /unset-value@1.0.0: - resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} - engines: {node: '>=0.10.0'} - dependencies: - has-value: 0.3.1 - isobject: 3.0.1 - dev: true - - /untildify@4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - dev: true - - /update-browserslist-db@1.0.11(browserslist@4.21.7): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.21.7 - escalade: 3.1.1 - picocolors: 1.0.0 - dev: true - - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - dependencies: - punycode: 2.3.0 - - /urix@0.1.0: - resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} - deprecated: Please see https://github.com/lydell/urix#deprecated - dev: true - - /use@3.1.1: - resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} - engines: {node: '>=0.10.0'} - dev: true - - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true - - /utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - dev: false - - /uuid@3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - dev: false - - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true - - /v8-compile-cache@2.3.0: - resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} - dev: false - - /v8-to-istanbul@9.1.0: - resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} - engines: {node: '>=10.12.0'} - dependencies: - '@jridgewell/trace-mapping': 0.3.18 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 - dev: true - - /vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - dev: false - - /verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - dev: false - - /walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - dependencies: - makeerror: 1.0.12 - dev: true - - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false - - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: false - - /which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: false - - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - - /word-wrap@1.2.4: - resolution: {integrity: sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==} - engines: {node: '>=0.10.0'} - dev: false - - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - dev: true - - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - /write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - dev: true - - /write@1.0.3: - resolution: {integrity: sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==} - engines: {node: '>=4'} - dependencies: - mkdirp: 0.5.6 - dev: false - - /xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - dev: true - - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true - - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true - - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - /yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - dev: true - - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true - - /yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - dev: true - - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - 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.8 - yargs-parser: 21.1.1 - dev: true - - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true - - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} diff --git a/anify-backend/prisma/schema.prisma b/anify-backend/prisma/schema.prisma deleted file mode 100644 index b38b334..0000000 --- a/anify-backend/prisma/schema.prisma +++ /dev/null @@ -1,146 +0,0 @@ -generator client { - provider = "prisma-client-js" - previewFeatures = ["orderByNulls", "clientExtensions", "postgresqlExtensions", "filteredRelationCount"] -} - -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} - -generator json { - provider = "prisma-json-types-generator" -} - -model Anime { - id String @id @default(nanoid(10)) - slug String - coverImage String? - bannerImage String? - trailer String? - status Status? - season Season @default(UNKNOWN) - /// [Title] - title Json - currentEpisode Int? - mappings Json @default("{}") - synonyms String[] - countryOfOrigin String? - description String? - duration Int? - color String? - year Int? - /// [Rating] - rating Json - /// [Popularity] - popularity Json - type String - format MediaFormat? @default(UNKNOWN) - /// [Relations] - relations Json[] @default([]) - totalEpisodes Float? - genres String[] - tags String[] - - /// [Episodes] - episodes Json @default("{\"latest\": {\"updatedAt\": 0, \"latestEpisode\": 0, \"latestTitle\": \"\"}, \"data\": []}") - - averageRating Float? - averagePopularity Float? - - /// [Artwork] - artwork Json[] @default([]) - - /// [Characters] - characters Json[] @default([]) - - @@map("anime") -} - -model Manga { - id String @id @default(nanoid(10)) - slug String - coverImage String? - bannerImage String? - status Status? - /// [Title] - title Json - mappings Json @default("{}") - synonyms String[] - countryOfOrigin String? - description String? - duration Int? - color String? - year Int? - /// [Rating] - rating Json - /// [Popularity] - popularity Json - type String - format MediaFormat? @default(UNKNOWN) - /// [Relations] - relations Json[] @default([]) - totalChapters Float? - totalVolumes Float? - genres String[] - tags String[] - - /// [Chapters] - chapters Json @default("{\"latest\": {\"updatedAt\": 0, \"latestChapter\": 0, \"latestTitle\": \"\"}, \"data\": []}") - - averageRating Float? - averagePopularity Float? - - /// [Artwork] - artwork Json[] @default([]) - - /// [Characters] - characters Json[] @default([]) - - @@map("manga") -} - -model SkipTimes { - id String @id @unique - /// [SkipTimes] - episodes Json[] -} - -model ApiKey { - id String @id @default(uuid()) - key String @unique - requestCount Int @default(0) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt -} - -enum Status { - FINISHED - RELEASING - NOT_YET_RELEASED - CANCELLED - HIATUS - UNKNOWN -} - -enum Season { - UNKNOWN - SPRING - SUMMER - FALL - WINTER -} - -enum MediaFormat { - UNKNOWN - TV - TV_SHORT - MOVIE - SPECIAL - OVA - ONA - MUSIC - MANGA - ONE_SHOT - NOVEL -} \ No newline at end of file diff --git a/anify-backend-recode/src/content/impl/chapters.ts b/anify-backend/src/content/impl/chapters.ts similarity index 100% rename from anify-backend-recode/src/content/impl/chapters.ts rename to anify-backend/src/content/impl/chapters.ts diff --git a/anify-backend/src/content/impl/chapters/index.ts b/anify-backend/src/content/impl/chapters/index.ts deleted file mode 100644 index b1c7667..0000000 --- a/anify-backend/src/content/impl/chapters/index.ts +++ /dev/null @@ -1,120 +0,0 @@ -import AniList from "../../../mapping/impl/information/anilist"; -import { Manga, Type, mangaProviders } from "../../../mapping"; -import Database from "../../../database"; -import { Chapter } from "../../../mapping/impl/manga"; - -export const fetchChapters = async (id: string): Promise => { - const media = await Database.info(id); - if (!media) return []; - - const mappings = media.mappings; - - const chapters: ChapterData[] = []; - - const promises: Promise[] = mappings.map(async (mapping) => { - const provider = mangaProviders[mapping.providerId]; - - if (!provider) return false; - - try { - const data = await provider.fetchChapters(String(mapping.id)).catch(() => []); - if (data && data.length === 0) return true; - - data?.map((chapter: Chapter) => { - if (!chapter.updatedAt) chapter.updatedAt = 0; - - const mixdrop = (media as Manga).chapters.data.find((x) => x.providerId === mapping.providerId)?.chapters.find((x) => x.id === chapter.id)?.mixdrop; - chapter.mixdrop = mixdrop; - }); - - if (data) { - chapters.push({ - providerId: mapping.providerId, - chapters: data, - }); - } - return true; - } catch (e) { - //console.log(colors.red(`Failed to fetch chapters for ${mapping.providerId} ${mapping.id}`)) - return false; - } - }); - - await Promise.all(promises); - - // Check if chapters length are different than before - let updatedAt = (media as Manga).chapters.latest.updatedAt; - let latestChapter = (media as Manga).chapters.latest.latestChapter; - let latestTitle = (media as Manga).chapters.latest.latestTitle; - - if (chapters.length != 0) { - if ((media as Manga).chapters.data.length != 0) { - for (const provider of (media as Manga).chapters.data) { - const providerChapters = provider.chapters; - const providerId = provider.providerId; - for (const provider of chapters) { - if (provider.providerId === providerId) { - //if (provider.chapters.length > providerChapters.length) { - // Find the latest chapter - const latest = provider.chapters.reduce((prev, current) => (prev.number > current.number ? prev : current)); - if ((latest.updatedAt ?? 0) > updatedAt && (latest.number > latestChapter || (latest.number === latestChapter && latest.title !== latestTitle)) && latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0 > updatedAt) { - updatedAt = latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0; - latestChapter = Number(latest.number); - latestTitle = String(latest.title); - } - //} - } - } - } - } else { - updatedAt = 0; - latestChapter = 0; - latestTitle = ""; - - for (const provider of chapters) { - const latest = provider.chapters.reduce((prev, current) => (prev.number > current.number ? prev : current)); - if ((latest.updatedAt ?? 0) > updatedAt && latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0 > updatedAt) { - updatedAt = latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0; - latestChapter = Number(latest.number); - latestTitle = String(latest.title); - } - } - } - } - - if (latestChapter === 0) (latestChapter = (media as Manga).chapters.latest.latestChapter), (latestTitle = (media as Manga).chapters.latest.latestTitle), (updatedAt = updatedAt === 0 && (media as Manga).chapters.latest.updatedAt !== 0 ? (media as Manga).chapters.latest.updatedAt : updatedAt); - - const aniList = new AniList(); - const anilistMedia = await aniList.getMedia(id); - - // Update basic information - await Database.update(id, Type.MANGA, { - status: anilistMedia?.status ?? media.status, - rating: { - anilist: anilistMedia?.rating ?? media.rating.anilist, - kitsu: media.rating.kitsu, - mal: media.rating.mal, - }, - popularity: { - anilist: anilistMedia?.popularity ?? media.popularity.anilist, - kitsu: media.popularity.kitsu, - mal: media.popularity.mal, - }, - chapters: { - latest: { - updatedAt, - latestChapter, - latestTitle, - }, - data: chapters, - }, - totalChapters: !(media as Manga).totalChapters || (media as Manga).totalChapters! < latestChapter ? latestChapter : (media as Manga).totalChapters, - }); - - return chapters; -}; - -export type ChapterData = { - providerId: string; - chapters: Chapter[]; -}; diff --git a/anify-backend-recode/src/content/impl/episodes.ts b/anify-backend/src/content/impl/episodes.ts similarity index 100% rename from anify-backend-recode/src/content/impl/episodes.ts rename to anify-backend/src/content/impl/episodes.ts diff --git a/anify-backend/src/content/impl/episodes/episodeCovers.ts b/anify-backend/src/content/impl/episodes/episodeCovers.ts deleted file mode 100644 index 145fdad..0000000 --- a/anify-backend/src/content/impl/episodes/episodeCovers.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Anime } from "../../../mapping"; -import AniList from "../../../mapping/impl/information/anilist"; -import Simkl from "../../../mapping/impl/information/simkl"; -import TMDB from "../../../mapping/impl/meta/tmdb"; - -export const loadEpisodeCovers = async (anime: Anime): Promise<{ episode: number; img: string }[] | undefined> => { - const simklMapping = anime.mappings.find((mapping) => mapping.providerId === "simkl"); - if (!simklMapping) { - const tmdbMapping = anime.mappings.find((mapping) => mapping.providerId === "tmdb"); - if (!tmdbMapping) { - // Fetch from Kitsu and AniList - const aniList = new AniList(); - const info = await aniList.getMedia(anime.id); - const streamingEpisodes = (info as any)?.streamingEpisodes ?? []; - - const episodes: { episode: number; img: string }[] = []; - - for (let i = 0; i < streamingEpisodes.length; i++) { - episodes.push({ - episode: i + 1, - img: streamingEpisodes[i].thumbnail, - }); - } - - if (episodes.length > 0) return episodes; - - return undefined; - - // Slow - /* - const kitsuMapping = anime.mappings.find((mapping) => mapping.providerId === "kitsuanime" || mapping.providerId === "kitsu"); - const kitsu = new Kitsu(); - return kitsu.getEpisodeCovers(kitsuMapping?.id ?? anime.id); - */ - } - - const tmdb = new TMDB(); - return tmdb.getEpisodeCovers(tmdbMapping.id, 1); - } else { - const simkl = new Simkl(); - return simkl.getEpisodeCovers(simklMapping.id); - } -}; diff --git a/anify-backend/src/content/impl/episodes/index.ts b/anify-backend/src/content/impl/episodes/index.ts deleted file mode 100644 index fc63fd6..0000000 --- a/anify-backend/src/content/impl/episodes/index.ts +++ /dev/null @@ -1,117 +0,0 @@ -import AniList from "../../../mapping/impl/information/anilist"; -import { animeProviders, Anime, Type } from "../../../mapping"; -import { Episode } from "../../../mapping/impl/anime"; -import Database from "../../../database"; - -export const fetchEpisodes = async (id: string): Promise => { - const media = await Database.info(id); - if (!media) return []; - - const mappings = media.mappings; - - const episodes: EpisodeData[] = []; - - const promises: Promise[] = mappings.map(async (mapping) => { - const provider = animeProviders[mapping.providerId]; - - if (!provider) return false; - - try { - const data = await provider.fetchEpisodes(String(mapping.id)).catch(() => []); - if (data && data.length === 0) return true; - - data?.map((episode) => { - if (!episode.updatedAt) episode.updatedAt = 0; - }); - - if (data) { - episodes.push({ - providerId: mapping.providerId, - episodes: data, - }); - } - return true; - } catch (e) { - //console.log(colors.red(`Failed to fetch episodes for ${mapping.providerId} ${mapping.id}`)) - return false; - } - }); - - await Promise.all(promises); - - // Check if chapters length are different than before - let updatedAt = (media as Anime).episodes.latest.updatedAt; - let latestEpisode = (media as Anime).episodes.latest.latestEpisode; - let latestTitle = (media as Anime).episodes.latest.latestTitle; - - if (episodes.length != 0) { - if ((media as Anime).episodes.data.length != 0) { - for (const provider of (media as Anime).episodes.data) { - const providerEpisodes = provider.episodes; - const providerId = provider.providerId; - for (const provider of episodes) { - if (provider.providerId === providerId) { - //if (provider.episodes.length > providerEpisodes.length) { - // Find the latest chapter - const latest = provider.episodes.reduce((prev, current) => (prev.number > current.number ? prev : current)); - if ((latest.updatedAt ?? 0) > updatedAt && (latest.number > latestEpisode || (latest.number === latestEpisode && latest.title !== latestTitle)) && latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0 > updatedAt) { - updatedAt = latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0; - latestEpisode = Number(latest.number); - latestTitle = String(latest.title); - } - //} - } - } - } - } else { - updatedAt = 0; - latestEpisode = 0; - latestTitle = ""; - - for (const provider of episodes) { - const latest = provider.episodes.reduce((prev, current) => (prev.number > current.number ? prev : current)); - if ((latest.updatedAt ?? 0) > updatedAt && latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0 > updatedAt) { - updatedAt = latest.updatedAt && !isNaN(Number(latest.updatedAt)) ? latest.updatedAt : 0; - latestEpisode = Number(latest.number); - latestTitle = String(latest.title); - } - } - } - } - - if (latestEpisode === 0) (latestEpisode = (media as Anime).episodes.latest.latestEpisode), (latestTitle = (media as Anime).episodes.latest.latestTitle), (updatedAt = updatedAt === 0 && (media as Anime).episodes.latest.updatedAt !== 0 ? (media as Anime).episodes.latest.updatedAt : updatedAt); - - const aniList = new AniList(); - const anilistMedia = await aniList.getMedia(id); - - // Update basic information - await Database.update(id, Type.ANIME, { - status: anilistMedia?.status ?? media.status, - rating: { - anilist: anilistMedia?.rating ?? media.rating.anilist, - kitsu: media.rating.kitsu, - mal: media.rating.mal, - }, - popularity: { - anilist: anilistMedia?.popularity ?? media.popularity.anilist, - kitsu: media.popularity.kitsu, - mal: media.popularity.mal, - }, - episodes: { - latest: { - updatedAt, - latestEpisode, - latestTitle, - }, - data: episodes, - }, - totalEpisodes: !(media as Anime).totalEpisodes || (media as Anime).totalEpisodes! < latestEpisode ? latestEpisode : (media as Anime).totalEpisodes, - }); - - return episodes; -}; - -export type EpisodeData = { - providerId: string; - episodes: Episode[]; -}; diff --git a/anify-backend-recode/src/content/impl/pages.ts b/anify-backend/src/content/impl/pages.ts similarity index 100% rename from anify-backend-recode/src/content/impl/pages.ts rename to anify-backend/src/content/impl/pages.ts diff --git a/anify-backend/src/content/impl/pages/index.ts b/anify-backend/src/content/impl/pages/index.ts deleted file mode 100644 index 45ad209..0000000 --- a/anify-backend/src/content/impl/pages/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { mangaProviders } from "../../../mapping"; -import { Chapter, Page } from "../../../mapping/impl/manga"; -import { fetchChapters } from "../chapters"; -import queues from "../../../worker"; - -export const fetchPages = async (id: string, providerId: string, readId: string): Promise => { - const provider = mangaProviders[providerId]; - - if (!provider) return null; - - const chapters = await fetchChapters(id); - - let chapter: Chapter | null = null; - for (const provider of chapters) { - if (provider.providerId === providerId) { - const chapData = provider.chapters; - for (const chap of chapData) { - if (chap.id === readId) { - chapter = chap; - break; - } - } - } - } - - try { - const data = await provider.fetchPages(readId).catch((err) => { - return null; - }); - if (!data) return null; - - if (chapter) await queues.uploadPages.add({ id, providerId, chapter, readId, pages: (data as Page[]) ?? [] }); - - return data; - } catch (e) { - return []; - } -}; diff --git a/anify-backend/src/content/impl/schedule/index.ts b/anify-backend/src/content/impl/schedule/index.ts deleted file mode 100644 index a87d65d..0000000 --- a/anify-backend/src/content/impl/schedule/index.ts +++ /dev/null @@ -1,74 +0,0 @@ -import Database from "../../../database"; -import { Anime } from "../../../mapping"; -import AniList from "../../../mapping/impl/information/anilist"; - -export const fetchSchedule = async (): Promise => { - const results: Anime[] = []; - - const aniList = new AniList(); - const schedule = await aniList.fetchSchedule(); - if (!schedule) return undefined; - - for (const show of schedule) { - const possible = await Database.info(String(show.media.id)); - if (possible) { - (possible as any).airingEpisode = show.episode; - (possible as any).airingAt = show.airingAt * 1000; - - results.push(possible as Anime); - } - } - - const formattedResponse: Schedule | undefined = results.reduce( - (acc: any, anime) => { - const day = new Date((anime as any).airingAt).getDay(); - - switch (day) { - case 0: - acc.sundaySchedule.push(anime); - break; - case 1: - acc.mondaySchedule.push(anime); - break; - case 2: - acc.tuesdaySchedule.push(anime); - break; - case 3: - acc.wednesdaySchedule.push(anime); - break; - case 4: - acc.thursdaySchedule.push(anime); - break; - case 5: - acc.fridaySchedule.push(anime); - break; - case 6: - acc.saturdaySchedule.push(anime); - break; - } - - return acc; - }, - { - sundaySchedule: [], - mondaySchedule: [], - tuesdaySchedule: [], - wednesdaySchedule: [], - thursdaySchedule: [], - fridaySchedule: [], - saturdaySchedule: [], - } - ); - - return formattedResponse; -}; - -interface Schedule { - sundaySchedule: Anime[]; - mondaySchedule: Anime[]; - tuesdaySchedule: Anime[]; - wednesdaySchedule: Anime[]; - thursdaySchedule: Anime[]; - fridaySchedule: Anime[]; - saturdaySchedule: Anime[]; -} diff --git a/anify-backend-recode/src/content/impl/sources.ts b/anify-backend/src/content/impl/sources.ts similarity index 100% rename from anify-backend-recode/src/content/impl/sources.ts rename to anify-backend/src/content/impl/sources.ts diff --git a/anify-backend/src/content/impl/sources/index.ts b/anify-backend/src/content/impl/sources/index.ts deleted file mode 100644 index 19652fe..0000000 --- a/anify-backend/src/content/impl/sources/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { animeProviders } from "../../../mapping"; -import { Source, StreamingServers, SubType } from "../../../mapping/impl/anime"; - -export const fetchSources = async (providerId: string, watchId: string, subType: SubType, server: StreamingServers): Promise => { - const provider = animeProviders[providerId]; - - if (!provider) return null; - - if (provider.subTypes && !provider.subTypes.includes(subType)) return null; - - try { - const data = await provider.fetchSources(watchId, subType, server).catch((err) => { - return null; - }); - if (!data) return null; - return data; - } catch (e) { - return null; - } -}; diff --git a/anify-backend/src/content/index.ts b/anify-backend/src/content/index.ts index 77dbb26..d8e5344 100644 --- a/anify-backend/src/content/index.ts +++ b/anify-backend/src/content/index.ts @@ -1,5 +1,5 @@ -import { fetchEpisodes } from "./impl/episodes"; import { fetchChapters } from "./impl/chapters"; +import { fetchEpisodes } from "./impl/episodes"; import { fetchSources } from "./impl/sources"; import { fetchPages } from "./impl/pages"; diff --git a/anify-backend/src/crawl.ts b/anify-backend/src/crawl.ts deleted file mode 100644 index 115837d..0000000 --- a/anify-backend/src/crawl.ts +++ /dev/null @@ -1,159 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -import dotenv from "dotenv"; -dotenv.config(); - -import colors from "colors"; -import { loadMapping } from "./lib/mappings"; - -import { CORS_PROXIES, fetchCorsProxies } from "./helper/proxies"; -import { AnimeInfo, MangaInfo } from "./mapping/impl/information"; -import { returnCreatedEntry } from "./lib/entry"; -import { existsSync, readFileSync, writeFileSync } from "fs"; -import { join } from "path"; -import Database from "./database"; -import { generateQueryBuilder } from "./helper/generator"; -import { Anime, Manga, Type } from "./mapping"; -import AniList from "./mapping/impl/information/anilist"; - -const type: Type = Type.MANGA; - -(async () => { - await fetchCorsProxies(); - if (CORS_PROXIES.length === 0) { - console.log(colors.yellow("WARNING: No CORS proxies were found. This may cause possible IP bans, rate limit issues, and more. It is recommended to run ") + colors.green("npm run create:proxies") + colors.yellow(" to generate a list of proxies.")); - } - - const aniList = new AniList(); - //const ids: string[] = await getPopularIds(); - // @ts-ignore - const ids: string[] = type === Type.ANIME ? await getAnimeIDs() : await getMangaIDs(); - //const ids: string[] = ["85470"]; - - const idsToRemove: string[] = []; - const media = await Database.fetchAll(type); - media.forEach((media) => { - idsToRemove.push(media.id); - }); - const numbersSet: Set = new Set(idsToRemove); - const cleanedIds: string[] = ids.filter((str) => !numbersSet.has(str)); - console.log(colors.gray("Found " + ids.length + " IDs, " + cleanedIds.length + " of which are not in the database.")); - - const chunkSize = 10; - for (let i = 0; i < cleanedIds.length; i += chunkSize) { - try { - const now = Date.now(); - const chunk = cleanedIds.slice(i, i + chunkSize); - const queries: string[] = []; - await Promise.all(chunk.map((id) => queries.push(generateQueryBuilder(id)))); - const results = await aniList.batchRequest(queries, 5); - - if (results.length === 0) continue; - const batchResults: AnimeInfo[] | MangaInfo[] = results - .reduce((accumulator, currentObject) => { - const mediaArrays = Object.values(currentObject).map((anime: any) => anime.media); - return accumulator.concat(...mediaArrays); - }, []) - .map((x: any) => { - if (!x) return null; - x.year = x.startDate?.year ?? x.seasonYear ?? 0; - return x; - }) - .filter(Boolean); - - const map = await Promise.all(batchResults.map((info: AnimeInfo | MangaInfo) => mapId(info))); - const data = map - .filter((x) => x.success && x.data !== undefined) - .map((x) => x.data as Anime[] | Manga[]) - .flat(); - - const toInsert = data.map((x) => returnCreatedEntry(x)); - - console.log(colors.gray("Starting to insert " + toInsert.length + " entries into the database.")); - - try { - await Database.createEntrys(toInsert as Anime[] | Manga[]).catch((err) => { - console.error(err); - console.log(colors.red("Create Many failed.")); - }); - } catch { - console.log(colors.red("Create Many error.")); - } - - console.log(colors.gray("Tried to insert " + toInsert.length + " entries into the database.")); - - const end = Date.now(); - - console.log(colors.green("Finished fetching data for " + map.filter((x) => x.success).length + "/" + map.length + `${type.toLowerCase()} \n Time taken: ` + (end - now) + "ms")); - } catch (err) { - console.log(colors.red("Chunk failed. Fatal error.")); - console.log(err); - } - } - console.log(colors.green("Crawling finished.")); - - async function mapId(aniData: AnimeInfo | MangaInfo) { - let isSuccess = false; - try { - const start = new Date(Date.now()); - const data = await loadMapping({ id: (aniData as any).id?.toString(), type: type }, aniData); - isSuccess = true; - - const end = new Date(Date.now()); - console.log(colors.gray("Finished fetching data. Request(s) took ") + colors.cyan(String(end.getTime() - start.getTime())) + colors.gray(" milliseconds.")); - return { id: (aniData as any).id?.toString(), success: isSuccess, data: data }; - } catch (err) { - console.log(err); - return { id: (aniData as any).id?.toString(), success: isSuccess }; - } - } - - async function getAnimeIDs(): Promise { - const idList = await (await fetch("https://raw.githubusercontent.com/5H4D0WILA/IDFetch/main/ids.txt")).text(); - const ids: string[] = idList.split("\n"); - return ids; - } - - /** - * @description Fetches all manga AniList ID's from AniList's sitemap - * @returns Promise - */ - async function getMangaIDs(): Promise { - const req1 = await fetch("https://anilist.co/sitemap/manga-0.xml"); - const data1 = await req1.text(); - const req2 = await fetch("https://anilist.co/sitemap/manga-1.xml"); - const data2 = await req2.text(); - - const ids1 = data1.match(/manga\/([0-9]+)/g)?.map((id) => { - return id.replace("manga/", ""); - }); - - const ids2 = data2.match(/manga\/([0-9]+)/g)?.map((id) => { - return id.replace("manga/", ""); - }); - return ids1?.concat(ids2 as string[]) ?? []; - } -})(); - -async function getPopularIds() { - if (existsSync(join(__dirname, "./popularIds.json"))) { - const popularIds = JSON.parse(readFileSync(join(__dirname, "./popularIds.json")).toString()) as string[]; - return uniqByFilter(popularIds); - } else { - const fetches = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((x) => fetch("https://c.delusionz.xyz/meta/anilist/trending?page=" + x + "&perPage=1000")); - const datas = await Promise.all(fetches); - const jsons = await Promise.all(datas.map((x) => x.json())); - - const ids = jsons - .map((x) => { - return x.results.map((y) => { - return y.id as string; - }) as string[]; - }) - .flat(); - writeFileSync(join(__dirname, "./popularIds.json"), JSON.stringify(ids, null, 4)); - return ids; - } -} -function uniqByFilter(array: T[]) { - return array.filter((value, index) => array.indexOf(value) === index); -} diff --git a/anify-backend-recode/src/database/impl/misc/recent.ts b/anify-backend/src/database/impl/misc/recent.ts similarity index 100% rename from anify-backend-recode/src/database/impl/misc/recent.ts rename to anify-backend/src/database/impl/misc/recent.ts diff --git a/anify-backend-recode/src/database/impl/misc/seasonal.ts b/anify-backend/src/database/impl/misc/seasonal.ts similarity index 100% rename from anify-backend-recode/src/database/impl/misc/seasonal.ts rename to anify-backend/src/database/impl/misc/seasonal.ts diff --git a/anify-backend-recode/src/database/impl/misc/stats.ts b/anify-backend/src/database/impl/misc/stats.ts similarity index 100% rename from anify-backend-recode/src/database/impl/misc/stats.ts rename to anify-backend/src/database/impl/misc/stats.ts diff --git a/anify-backend-recode/src/database/impl/modify/create.ts b/anify-backend/src/database/impl/modify/create.ts similarity index 100% rename from anify-backend-recode/src/database/impl/modify/create.ts rename to anify-backend/src/database/impl/modify/create.ts diff --git a/anify-backend-recode/src/database/impl/modify/delete.ts b/anify-backend/src/database/impl/modify/delete.ts similarity index 100% rename from anify-backend-recode/src/database/impl/modify/delete.ts rename to anify-backend/src/database/impl/modify/delete.ts diff --git a/anify-backend-recode/src/database/impl/modify/get.ts b/anify-backend/src/database/impl/modify/get.ts similarity index 100% rename from anify-backend-recode/src/database/impl/modify/get.ts rename to anify-backend/src/database/impl/modify/get.ts diff --git a/anify-backend-recode/src/database/impl/modify/update.ts b/anify-backend/src/database/impl/modify/update.ts similarity index 100% rename from anify-backend-recode/src/database/impl/modify/update.ts rename to anify-backend/src/database/impl/modify/update.ts diff --git a/anify-backend-recode/src/database/impl/search/search.ts b/anify-backend/src/database/impl/search/search.ts similarity index 100% rename from anify-backend-recode/src/database/impl/search/search.ts rename to anify-backend/src/database/impl/search/search.ts diff --git a/anify-backend-recode/src/database/impl/search/searchAdvanced.ts b/anify-backend/src/database/impl/search/searchAdvanced.ts similarity index 100% rename from anify-backend-recode/src/database/impl/search/searchAdvanced.ts rename to anify-backend/src/database/impl/search/searchAdvanced.ts diff --git a/anify-backend-recode/src/database/impl/skipTimes/createSkipTimes.ts b/anify-backend/src/database/impl/skipTimes/createSkipTimes.ts similarity index 100% rename from anify-backend-recode/src/database/impl/skipTimes/createSkipTimes.ts rename to anify-backend/src/database/impl/skipTimes/createSkipTimes.ts diff --git a/anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts b/anify-backend/src/database/impl/skipTimes/getSkipTimes.ts similarity index 100% rename from anify-backend-recode/src/database/impl/skipTimes/getSkipTimes.ts rename to anify-backend/src/database/impl/skipTimes/getSkipTimes.ts diff --git a/anify-backend-recode/src/database/impl/skipTimes/updateSkipTimes.ts b/anify-backend/src/database/impl/skipTimes/updateSkipTimes.ts similarity index 100% rename from anify-backend-recode/src/database/impl/skipTimes/updateSkipTimes.ts rename to anify-backend/src/database/impl/skipTimes/updateSkipTimes.ts diff --git a/anify-backend/src/database/index.ts b/anify-backend/src/database/index.ts index f41dc30..f393403 100644 --- a/anify-backend/src/database/index.ts +++ b/anify-backend/src/database/index.ts @@ -1,420 +1,94 @@ -import { randomUUID } from "crypto"; -import { Anime, Format, Genres, Manga, Type } from "../mapping"; -import { info, media, prisma, recent, search, searchAdvanced, seasonal as seasonalPostgres } from "./postgresql"; - -export default class Database { - private static type = "postgresql"; - - static async initializeDatabase() { - if (this.type === "postgresql") { - await prisma.$connect(); - await prisma.$executeRaw`CREATE EXTENSION IF NOT EXISTS pg_trgm;`; - await prisma.$executeRaw`create or replace function most_similar(text, text[]) returns double precision - language sql as $$ - select max(similarity($1,x)) from unnest($2) f(x) - $$;`; - } - } - - static async search(query: string, type: Type, formats: Format[], page: number, perPage: number): Promise { - if (this.type === "postgresql") { - return await search(query, type, formats, page, perPage); - } else { - return []; - } - } - - static async searchAdvanced(query: string, type: Type, formats: Format[], page: number, perPage: number, genres: Genres[] = [], genresExcluded: Genres[] = [], year = 0, tags: string[] = [], tagsExcluded: string[] = []): Promise { - if (this.type === "postgresql") { - return await searchAdvanced(query, type.toUpperCase() as Type, formats, page, 40, genres as Genres[], genresExcluded as Genres[], year, tags, tagsExcluded); - } else { - return []; - } - } - - static async seasonal(trending: Anime[] | Manga[], popular: Anime[] | Manga[], top: Anime[] | Manga[], seasonal: Anime[] | Manga[]) { - if (this.type === "postgresql") { - return await seasonalPostgres(trending, popular, top, seasonal); - } else { - return { - trending: [], - popular: [], - top: [], - seasonal: [], - }; - } - } - - static async info(id: string): Promise { - if (this.type === "postgresql") { - return (await info(id)) as Anime | Manga; - } else { - return null; - } - } - - static async media(providerId: string, id: string): Promise { - if (this.type === "postgresql") { - return (await media(providerId, id)) as Anime | Manga; - } else { - return null; - } - } - - static async relations(id: string): Promise { - if (this.type !== "postgresql") { - return null; - } - - const info = await this.info(id); - const relations = info?.relations ?? []; - - const relatedMediaPromises = relations.map(async (relation) => { - const media = await this.info(relation.id); - Object.assign(media ?? {}, { relationType: relation.relationType }); - return media as Anime | Manga | null; - }); - - const relatedMedia = await Promise.all(relatedMediaPromises); - const filteredMedia = relatedMedia.filter((media) => media !== null) as (Anime | Manga)[]; - - return filteredMedia as Anime[] | Manga[]; - } - - static async fetchAll(type: Type): Promise { - if (this.type === "postgresql") { - if (type === Type.ANIME) { - return (await prisma.anime.findMany()) as any[]; - } else { - return (await prisma.manga.findMany()) as any[]; - } - } else { - return []; - } - } - - static async update(id: string, type: Type, data: any): Promise { - if (this.type === "postgresql") { - if (type === Type.ANIME) { - await prisma.anime.update({ - where: { - id: id, - }, - data, - }); - } else { - await prisma.manga.update({ - where: { - id: id, - }, - data, - }); - } - } - } - - static async delete(id: string): Promise { - if (this.type === "postgresql") { - const data = await info(id); - if (data?.type === Type.ANIME) { - await prisma.anime.delete({ - where: { - id: data?.id, - }, - }); - } else { - await prisma.manga.delete({ - where: { - id: data?.id, - }, - }); - } - } else { - return; - } - } - - static async createEntry(media: Anime | Manga): Promise { - if (this.type === "postgresql") { - if (media.type === Type.ANIME) { - await prisma.anime.create({ - data: media, - }); - } else { - await prisma.manga.create({ - data: media, - }); - } - } - } - - static async createEntrys(media: Anime[] | Manga[]): Promise { - if (this.type === "postgresql") { - if (media[0]?.type === Type.ANIME) { - await prisma.anime.createMany({ - data: media, - skipDuplicates: true, - }); - } else { - await prisma.manga.createMany({ - data: media, - skipDuplicates: true, - }); - } - } - } - - static async findSkipTimes(id: string) { - if (this.type === "postgresql") { - return await prisma.skipTimes.findUnique({ - where: { - id: id, - }, - }); - } - } - - static async updateSkipTimes(id: string, episodes: { duration: string; intro: { start: number; end: number }; outro: { start: number; end: number }; number: number }[]): Promise { - if (this.type === "postgresql") { - await prisma.skipTimes.upsert({ - where: { - id: id, - }, - update: { - episodes: episodes, - }, - create: { - id: id, - episodes: episodes, - }, - }); - } - } - - static async createAPIKey(key: string): Promise { - if (this.type === "postgresql") { - if (await prisma.apiKey.findFirst({ where: { key } })) { - return key; - } - await prisma.apiKey.create({ - data: { - key, - }, - }); - - return key; - } else { - return ""; - } - } - - static async insertAPIKey(data: any): Promise { - if (this.type === "postgresql") { - if (await prisma.apiKey.findFirst({ where: { key: data.key } })) { - return; - } - await prisma.apiKey.create({ - data, - }); - - return; - } else { - return; - } - } - - static async updateKeyRequests(key: string, requests: number): Promise { - if (this.type === "postgresql") { - await prisma.apiKey.update({ - where: { - key, - }, - data: { - requestCount: requests, - }, - }); - } - } - - static async assignKey(key: string, id: string): Promise { - if (this.type === "postgresql") { - const exists = await prisma.apiKey.findFirst({ - where: { - id, - }, - }); - - if (exists) { - return false; - } - - await prisma.apiKey.update({ - where: { - key, - }, - data: { - id, - }, - }); - - return true; - } - } - - static async unassignKey(key: string): Promise { - if (this.type === "postgresql") { - const exists = await prisma.apiKey.findFirst({ - where: { - key, - }, - }); - - if (!exists) { - return false; - } - - await prisma.apiKey.update({ - where: { - key, - }, - data: { - id: randomUUID(), - }, - }); - - return true; - } - } - - static async getKeyById(id: string): Promise { - if (this.type === "postgresql") { - return await prisma.apiKey.findFirst({ - where: { - id, - }, - }); - } - } - - static async deleteKey(key: string): Promise { - if (this.type === "postgresql") { - await prisma.apiKey.delete({ - where: { - key, - }, - }); - } - } - - static async fetchAPIKey(key: string): Promise { - if (this.type === "postgresql") { - return await prisma.apiKey.findUnique({ - where: { - key, - }, - }); - } else { - return null; - } - } - - static async fetchAPIKeys(): Promise { - if (this.type === "postgresql") { - const apiKeys = await prisma.apiKey.findMany(); - return apiKeys.map((key) => key.key); - } else { - return []; - } - } - - static async fetchAllAPIKeys(): Promise { - if (this.type === "postgresql") { - const apiKeys = await prisma.apiKey.findMany(); - return apiKeys; - } else { - return []; - } - } - - static async fetchAllSkipTimes(): Promise { - if (this.type === "postgresql") { - const skipTimes = await prisma.skipTimes.findMany(); - return skipTimes; - } else { - return []; - } - } - - static async recent(type: Type, formats: Format[], page = 1): Promise { - if (this.type === "postgresql") { - const data = await recent(type, formats, page, 30); - return data; - } else { - return []; - } - } - - static async clear(): Promise<{ anime: number; manga: number; skipTimes: number; apiKeys: number }> { - if (this.type === "postgresql") { - const animeDelete = prisma.anime.deleteMany({}); - const mangaDelete = prisma.manga.deleteMany({}); - const skipTimesDelete = prisma.skipTimes.deleteMany({}); - const apiKeyDelete = prisma.apiKey.deleteMany({}); - - const [animeResult, mangaResult, skipTimesResult, apiKeyResults] = await Promise.all([animeDelete, mangaDelete, skipTimesDelete, apiKeyDelete]); - return { - anime: animeResult.count, - manga: mangaResult.count, - skipTimes: skipTimesResult.count, - apiKeys: apiKeyResults.count, - }; - } else { - return { - anime: 0, - manga: 0, - skipTimes: 0, - apiKeys: 0, - }; - } - } - - static async count() { - const data = { - anime: 0, - manga: 0, - novels: 0, - apiKeys: 0, - skipTimes: 0, - }; - - if (this.type === "postgresql") { - const manga = await prisma.manga.count(); - const mangaNotNovels = await prisma.manga.count({ - where: { - format: { - not: "NOVEL", - }, - }, - }); - - data.anime = await prisma.anime.count(); - data.manga = mangaNotNovels; - data.novels = manga - mangaNotNovels; - - data.apiKeys = await prisma.apiKey.count(); - - const totalSkipTimes = await prisma.skipTimes.findMany(); - - for (const skipTime of totalSkipTimes) { - const episodes = skipTime.episodes; - for (let i = 0; i < episodes.length; i++) { - if (episodes[i].outro?.end != 0) { - data.skipTimes++; - } - } - } - } - - return data; - } -} +import { Database } from "bun:sqlite"; + +export const db = new Database("db.sqlite"); + +export const init = async () => { + const anime = ` + CREATE TABLE IF NOT EXISTS anime ( + id TEXT PRIMARY KEY, + slug TEXT, + coverImage TEXT, + bannerImage TEXT, + trailer TEXT, + status TEXT, + season TEXT DEFAULT 'UNKNOWN', + title JSON, + currentEpisode INTEGER, + mappings JSON DEFAULT '[]', + synonyms JSON DEFAULT '[]', + countryOfOrigin TEXT, + description TEXT, + duration INTEGER, + color TEXT, + year INTEGER, + rating JSON, + popularity JSON, + type TEXT, + format TEXT DEFAULT 'UNKNOWN', + relations JSON DEFAULT '[]', + totalEpisodes REAL, + genres JSON DEFAULT '[]', + tags JSON DEFAULT '[]', + episodes JSON DEFAULT '{"latest": {"updatedAt": 0, "latestEpisode": 0, "latestTitle": ""}, "data": []}', + averageRating REAL, + averagePopularity REAL, + artwork JSON DEFAULT '[]', + characters JSON DEFAULT '[]' + ); + `; + + const manga = ` + CREATE TABLE IF NOT EXISTS manga ( + id TEXT PRIMARY KEY, + slug TEXT, + coverImage TEXT, + bannerImage TEXT, + status TEXT, + title JSON, + mappings JSON DEFAULT '[]', + synonyms JSON DEFAULT '[]', + countryOfOrigin TEXT, + description TEXT, + duration INTEGER, + color TEXT, + year INTEGER, + rating JSON, + popularity JSON, + type TEXT, + format TEXT DEFAULT 'UNKNOWN', + relations JSON DEFAULT '[]', + currentChapter INTEGER, + totalChapters REAL, + totalVolumes REAL, + genres JSON DEFAULT '[]', + tags JSON DEFAULT '[]', + chapters JSON DEFAULT '{"latest": {"updatedAt": 0, "latestChapter": 0, "latestTitle": ""}, "data": []}', + averageRating REAL, + averagePopularity REAL, + artwork JSON DEFAULT '[]', + characters JSON DEFAULT '[]' + ); + `; + + const skipTimes = ` + CREATE TABLE IF NOT EXISTS skipTimes ( + id TEXT PRIMARY KEY, + episodes JSON DEFAULT '{}' + ); + `; + + const apiKey = ` + CREATE TABLE IF NOT EXISTS apiKey ( + id TEXT PRIMARY KEY, + key TEXT, + requestCount INTEGER DEFAULT 0, + createdAt INTEGER DEFAULT 0, + updatedAt INTEGER DEFAULT 0 + ); + `; + + await db.query(anime).run(); + await db.query(manga).run(); + await db.query(skipTimes).run(); + await db.query(apiKey).run(); +}; diff --git a/anify-backend/src/database/postgresql.ts b/anify-backend/src/database/postgresql.ts deleted file mode 100644 index df5b8b4..0000000 --- a/anify-backend/src/database/postgresql.ts +++ /dev/null @@ -1,661 +0,0 @@ -import { PrismaClient } from "@prisma/client"; -import { Prisma as Pris } from "@prisma/client"; -import { Anime, Format, Genres, Manga, ProviderType, Type } from "../mapping"; -import { EpisodeData } from "../content/impl/episodes"; -import { ChapterData } from "../content/impl/chapters"; -export * from "@prisma/client"; - -const averageMetric = (object: PrismaJson.MetaSitesMetric) => { - let average = 0, - validCount = 0; - for (const [_, v] of Object.entries(object)) { - if (v && typeof v === "number") { - average += v; - validCount++; - } - } - - return validCount === 0 ? 0 : Number.parseFloat((average / validCount).toFixed(2)); -}; - -const $prisma = new PrismaClient({ - log: ["error"], -}); - -const dedupeFields = ["synonyms", "genres"]; - -$prisma.$use(async (params, next) => { - if (params.model === "Manga" || params.model === "Anime") { - if (!params?.args) return next(params); - - for (const field of dedupeFields) { - if (params.args["data"] && params.args["data"][field]) { - params.args["data"][field] = Array.from(new Set(params.args["data"][field])); - } - } - } - - return next(params); -}); - -const modifiedPrisma = $prisma.$extends({ - query: { - anime: { - async $allOperations({ model, operation, args, query }) { - const result = await query(args); - - if (result?.synonyms) result.synonyms = Array.from(new Set(result.synonyms)); - if (result?.genres) result.genres = Array.from(new Set(result.genres)); - - return result; - }, - }, - manga: { - async $allOperations({ model, operation, args, query }) { - const result = await query(args); - - if (result?.synonyms) result.synonyms = Array.from(new Set(result.synonyms)); - if (result?.genres) result.genres = Array.from(new Set(result.genres)); - - return result; - }, - }, - }, - result: { - anime: { - save: { - needs: { id: true }, - compute(anime) { - delete anime["averagePopularity"]; - delete anime["averageRating"]; - - return () => $prisma.anime.update({ where: { id: anime.id }, data: anime }); - }, - }, - averageRating: { - needs: { rating: true }, - compute(anime) { - return averageMetric(anime.rating); - }, - }, - averagePopularity: { - needs: { popularity: true }, - compute(anime) { - return averageMetric(anime.popularity); - }, - }, - }, - manga: { - save: { - needs: { id: true }, - compute(manga) { - delete manga["averagePopularity"]; - delete manga["averageRating"]; - - return () => $prisma.manga.update({ where: { id: manga.id }, data: manga }); - }, - }, - averageRating: { - needs: { rating: true }, - compute(manga) { - return averageMetric(manga.rating); - }, - }, - averagePopularity: { - needs: { popularity: true }, - compute(manga) { - return averageMetric(manga.popularity); - }, - }, - }, - }, -}); - -const globalForPrisma = global as unknown as { prisma: typeof modifiedPrisma }; - -export const prisma = globalForPrisma.prisma || modifiedPrisma; - -if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = modifiedPrisma; - -declare global { - namespace PrismaJson { - type Title = { - english: string | null; - romaji: string | null; - native: string | null; - }; - - type Rating = MetaSitesMetric; - type Popularity = MetaSitesMetric; - - type MetaSitesMetric = { - anilist: number | SplitEntryMapping | null; - mal: number | SplitEntryMapping | null; - kitsu: number | SplitEntryMapping | null; - }; - - type SkipTimes = { - duration?: string; - number: number; - intro: { - start: number; - end: number; - }; - outro: { - start: number; - end: number; - }; - }; - - type Episodes = { - latest: { - updatedAt: number; - latestEpisode: number; - latestTitle: string; - }; - data: EpisodeData[]; - }; - - type Chapters = { - latest: { - updatedAt: number; - latestChapter: number; - latestTitle: string; - }; - data: ChapterData[]; - }; - - type Artwork = { - type: "banner" | "poster" | "clear_logo" | "top_banner" | "icon" | "clear_art"; - img: string; - providerId: string; - }; - - type Relations = { - id: string; - type: Type; - title: Title; - format: Format; - relationType: string; - }; - - type Characters = { - name: string; - image: string; - voiceActor: { - name: string; - image: string; - }; - }; - - type SplitEntryMapping = `${number}@${number}-${number}`; - } -} - -export const seasonal = async (trending: Anime[] | Manga[], popular: Anime[] | Manga[], top: Anime[] | Manga[], seasonal: Anime[] | Manga[]) => { - const trend = trending.map((a) => String(a.aniListId)); - const pop = popular.map((a) => String(a.aniListId)); - const t = top.map((a) => String(a.aniListId)); - const season = seasonal.map((a) => String(a.aniListId)); - - if (trending[0] && trending[0].type === Type.ANIME) { - const trending = await prisma.anime.findMany({ - where: { - id: { - in: [...trend], - }, - }, - }); - - const popular = await prisma.anime.findMany({ - where: { - id: { - in: [...pop], - }, - }, - }); - - const top = await prisma.anime.findMany({ - where: { - id: { - in: [...t], - }, - }, - }); - - const seasonal = await prisma.anime.findMany({ - where: { - id: { - in: [...season], - }, - }, - }); - - trending.map((media) => { - media.characters = []; - }); - popular.map((media) => { - media.characters = []; - }); - top.map((media) => { - media.characters = []; - }); - seasonal.map((media) => { - media.characters = []; - }); - - return { trending, popular, top, seasonal }; - } else { - const trending = await prisma.manga.findMany({ - where: { - id: { - in: [...trend], - }, - }, - }); - - const popular = await prisma.manga.findMany({ - where: { - id: { - in: [...pop], - }, - }, - }); - - const top = await prisma.manga.findMany({ - where: { - id: { - in: [...t], - }, - }, - }); - - const seasonal = await prisma.manga.findMany({ - where: { - id: { - in: [...season], - }, - }, - }); - - trending.map((media) => { - media.characters = []; - }); - popular.map((media) => { - media.characters = []; - }); - top.map((media) => { - media.characters = []; - }); - seasonal.map((media) => { - media.characters = []; - }); - - return { trending, popular, top, seasonal }; - } -}; - -export const search = async (query: string, type: Type, formats: Format[], page: number, perPage: number) => { - const skip = page > 0 ? perPage * (page - 1) : 0; - let where; - - if (type === Type.ANIME) { - where = Pris.sql` - WHERE - ( - ${"%" + query + "%"} ILIKE ANY("anime".synonyms) - OR ${"%" + query + "%"} % ANY("anime".synonyms) - OR "anime".title->>'english' ILIKE ${"%" + query + "%"} - OR "anime".title->>'romaji' ILIKE ${"%" + query + "%"} - OR "anime".title->>'native' ILIKE ${"%" + query + "%"} - ) - ${ - formats.length > 0 - ? Pris.sql`AND "anime"."format" IN (${Pris.join( - formats.map((f) => Pris.raw(`'${f}'`)), - ", " - )})` - : Pris.empty - } - `; - } else { - where = Pris.sql` - WHERE - ( - ${"%" + query + "%"} ILIKE ANY("manga".synonyms) - OR ${"%" + query + "%"} % ANY("manga".synonyms) - OR "manga".title->>'english' ILIKE ${"%" + query + "%"} - OR "manga".title->>'romaji' ILIKE ${"%" + query + "%"} - OR "manga".title->>'native' ILIKE ${"%" + query + "%"} - ) - ${ - formats.length > 0 - ? Pris.sql`AND "manga"."format" IN (${Pris.join( - formats.map((f) => Pris.raw(`'${f}'`)), - ", " - )})` - : Pris.empty - } - `; - } - - let [count, results] = [0, []]; - if (type === Type.ANIME) { - [count, results] = await prisma.$transaction([ - prisma.$queryRaw` - SELECT COUNT(*) FROM "anime" - ${where} - `, - prisma.$queryRaw` - SELECT * FROM "anime" - ${where} - ORDER BY - (CASE WHEN "anime".title->>'english' IS NOT NULL THEN similarity(LOWER("anime".title->>'english'), LOWER(${query})) ELSE 0 END, - + CASE WHEN "anime".title->>'romaji' IS NOT NULL THEN similarity(LOWER("anime".title->>'romaji'), LOWER(${query})) ELSE 0 END, - + CASE WHEN "anime".title->>'native' IS NOT NULL THEN similarity(LOWER("anime".title->>'native'), LOWER(${query})) ELSE 0 END, - + CASE WHEN synonyms IS NOT NULL THEN most_similar(LOWER(${query}), synonyms) ELSE 0 END) - DESC - LIMIT ${perPage} - OFFSET ${skip} - `, - ]); - } else { - [count, results] = await prisma.$transaction([ - prisma.$queryRaw` - SELECT COUNT(*) FROM "manga" - ${where} - `, - prisma.$queryRaw` - SELECT * FROM "manga" - ${where} - ORDER BY - (CASE WHEN "manga".title->>'english' IS NOT NULL THEN similarity(LOWER("manga".title->>'english'), LOWER(${query})) ELSE 0 END, - + CASE WHEN "manga".title->>'romaji' IS NOT NULL THEN similarity(LOWER("manga".title->>'romaji'), LOWER(${query})) ELSE 0 END, - + CASE WHEN "manga".title->>'native' IS NOT NULL THEN similarity(LOWER("manga".title->>'native'), LOWER(${query})) ELSE 0 END, - + CASE WHEN synonyms IS NOT NULL THEN most_similar(LOWER(${query}), synonyms) ELSE 0 END) - DESC - LIMIT ${perPage} - OFFSET ${skip} - `, - ]); - } - - const total = Number(count[0].count); - const lastPage = Math.ceil(Number(total) / perPage); - - return results; -}; - -export const searchAdvanced = async (query: string, type: Type, formats: Format[], page: number, perPage: number, genres: Genres[] = [], genresExcluded: Genres[] = [], year = 0, tags: string[] = [], tagsExcluded: string[] = []) => { - const skip = page > 0 ? perPage * (page - 1) : 0; - let where; - - if (type === Type.ANIME) { - where = Pris.sql` - WHERE - ( - ${"%" + query + "%"} ILIKE ANY("anime".synonyms) - OR ${"%" + query + "%"} % ANY("anime".synonyms) - OR "anime".title->>'english' ILIKE ${"%" + query + "%"} - OR "anime".title->>'romaji' ILIKE ${"%" + query + "%"} - OR "anime".title->>'native' ILIKE ${"%" + query + "%"} - ) - ${ - formats.length > 0 - ? Pris.sql`AND "anime"."format" IN (${Pris.join( - formats.map((f) => Pris.raw(`'${f}'`)), - ", " - )})` - : Pris.empty - } - ${ - genres && genres.length > 0 - ? Pris.sql`AND ARRAY[${Pris.join( - genres.map((g) => Pris.raw(`'${g}'`)), - ", " - )}] <@ "anime"."genres"` - : Pris.empty - } - ${ - genresExcluded.length > 0 - ? Pris.sql`AND NOT ARRAY[${Pris.join( - genresExcluded.map((g) => Pris.raw(`'${g}'`)), - ", " - )}] <@ "anime"."genres"` - : Pris.empty - } - ${ - tags && tags.length > 0 - ? Pris.sql`AND ARRAY[${Pris.join( - tags.map((g) => Pris.raw(`'${g}'`)), - ", " - )}] <@ "anime"."tags"` - : Pris.empty - } - ${ - tagsExcluded.length > 0 - ? Pris.sql`AND NOT ARRAY[${Pris.join( - tagsExcluded.map((g) => Pris.raw(`'${g}'`)), - ", " - )}] <@ "anime"."tags"` - : Pris.empty - } - ${year > 0 ? Pris.sql`AND "anime"."year" = ${year}` : Pris.empty} - - `; - } else { - where = Pris.sql` - WHERE - ( - ${"%" + query + "%"} ILIKE ANY("manga".synonyms) - OR ${"%" + query + "%"} % ANY("manga".synonyms) - OR "manga".title->>'english' ILIKE ${"%" + query + "%"} - OR "manga".title->>'romaji' ILIKE ${"%" + query + "%"} - OR "manga".title->>'native' ILIKE ${"%" + query + "%"} - ) - ${ - formats.length > 0 - ? Pris.sql`AND "manga"."format" IN (${Pris.join( - formats.map((f) => Pris.raw(`'${f}'`)), - ", " - )})` - : Pris.empty - } - ${ - genres && genres.length > 0 - ? Pris.sql`AND ARRAY[${Pris.join( - genres.map((g) => Pris.raw(`'${g}'`)), - ", " - )}] <@ "manga"."genres"` - : Pris.empty - } - ${ - tags && tags.length > 0 - ? Pris.sql`AND ARRAY[${Pris.join( - tags.map((g) => Pris.raw(`'${g}'`)), - ", " - )}] <@ "manga"."tags"` - : Pris.empty - } - `; - } - - let [count, results] = [0, []]; - if (type === Type.ANIME) { - [count, results] = await prisma.$transaction([ - prisma.$queryRaw` - SELECT COUNT(*) FROM "anime" - ${where} - `, - prisma.$queryRaw` - SELECT * FROM "anime" - ${where} - ORDER BY - (CASE WHEN "anime".title->>'english' IS NOT NULL THEN similarity(LOWER("anime".title->>'english'), LOWER(${query})) ELSE 0 END, - + CASE WHEN "anime".title->>'romaji' IS NOT NULL THEN similarity(LOWER("anime".title->>'romaji'), LOWER(${query})) ELSE 0 END, - + CASE WHEN "anime".title->>'native' IS NOT NULL THEN similarity(LOWER("anime".title->>'native'), LOWER(${query})) ELSE 0 END, - + CASE WHEN synonyms IS NOT NULL THEN most_similar(LOWER(${query}), synonyms) ELSE 0 END) - DESC - LIMIT ${perPage} - OFFSET ${skip} - `, - ]); - } else { - [count, results] = await prisma.$transaction([ - prisma.$queryRaw` - SELECT COUNT(*) FROM "manga" - ${where} - `, - prisma.$queryRaw` - SELECT * FROM "manga" - ${where} - ORDER BY - (CASE WHEN "manga".title->>'english' IS NOT NULL THEN similarity(LOWER("manga".title->>'english'), LOWER(${query})) ELSE 0 END, - + CASE WHEN "manga".title->>'romaji' IS NOT NULL THEN similarity(LOWER("manga".title->>'romaji'), LOWER(${query})) ELSE 0 END, - + CASE WHEN "manga".title->>'native' IS NOT NULL THEN similarity(LOWER("manga".title->>'native'), LOWER(${query})) ELSE 0 END, - + CASE WHEN synonyms IS NOT NULL THEN most_similar(LOWER(${query}), synonyms) ELSE 0 END) - DESC - LIMIT ${perPage} - OFFSET ${skip} - `, - ]); - } - - const total = Number(count[0].count); - const lastPage = Math.ceil(Number(total) / perPage); - - return results; -}; - -export const info = async (id: string): Promise => { - let media: any = await prisma.anime.findUnique({ - where: { id: String(id) }, - }); - - if (!media) { - media = await prisma.manga.findUnique({ - where: { id: String(id) }, - }); - } - - if (!media) return null; - - if (media.synonyms) media.synonyms = Array.from(new Set(media.synonyms)); - if (media.genres) media.genres = Array.from(new Set(media.genres)); - - return media; -}; - -export const media = async (providerId: string, id: string): Promise => { - try { - const data = await ( - await prisma.$queryRaw(Pris.sql` - SELECT * FROM "anime" - WHERE "anime"."mappings" @> '[{"providerId": "${Pris.raw(providerId)}", "id": "${Pris.raw(id)}"}]' - `) - )?.[0]; - - if (!data) { - const data = await ( - await prisma.$queryRaw(Pris.sql` - SELECT * FROM "manga" - WHERE "manga"."mappings" @> '[{"providerId": "${Pris.raw(providerId)}", "id": "${Pris.raw(id)}"}]' - `) - )?.[0]; - - return data as Anime | Manga; - } else { - return data as Anime | Manga; - } - } catch (error) { - console.error("Error fetching media:", error); - return null; - } -}; - -export const recent = async (type: Type, formats: Format[], page: number, perPage: number): Promise => { - const skip = page > 0 ? perPage * (page - 1) : 0; - let where; - - if (type === Type.ANIME) { - where = Pris.sql` - ${ - formats.length > 0 - ? Pris.sql`WHERE "anime"."format" IN (${Pris.join( - formats.map((f) => Pris.raw(`'${f}'`)), - ", " - )})` - : Pris.empty - } - `; - } else { - where = Pris.sql` - ${ - formats.length > 0 - ? Pris.sql`WHERE "manga"."format" IN (${Pris.join( - formats.map((f) => Pris.raw(`'${f}'`)), - ", " - )})` - : Pris.empty - } - `; - } - - let [count, results] = [0, []]; - if (type === Type.ANIME) { - [count, results] = await prisma.$transaction([ - prisma.$queryRaw` - SELECT COUNT(*) FROM "anime" - ${where} - `, - prisma.$queryRaw` - SELECT * FROM "anime" - ${where} - ORDER BY - "anime".episodes->>'latest' DESC - LIMIT ${perPage} - OFFSET ${skip} - `, - ]); - } else { - [count, results] = await prisma.$transaction([ - prisma.$queryRaw` - SELECT COUNT(*) FROM "manga" - ${where} - `, - prisma.$queryRaw` - SELECT * FROM "manga" - ${where} - ORDER BY - "manga".chapters->>'latest' DESC - LIMIT ${perPage} - OFFSET ${skip} - `, - ]); - } - - const total = Number(count[0].count); - const lastPage = Math.ceil(Number(total) / perPage); - - const newResults: any[] = []; - for (const result of results) { - if ((result as Anime | Manga).type === Type.ANIME ? (result as Anime).episodes.latest.latestEpisode === 0 : (result as Manga).chapters.latest.latestChapter === 0) continue; - - const updatedAt = ((result as Anime | Manga).type === Type.ANIME ? (result as Anime).episodes : (result as Manga).chapters).latest.updatedAt; - - newResults.push({ - ...(result as Anime | Manga), - updatedAt: String(updatedAt).length === 0 ? 0 : new Date(Number(updatedAt)).getTime(), - }); - } - - // Sort by updatedAt - newResults.sort((a, b) => (b.updatedAt as number) - (a.updatedAt as number)); - - // Remove updatedAt - for (const result of newResults) { - delete result.updatedAt; - } - - return newResults; -}; diff --git a/anify-backend/src/env.ts b/anify-backend/src/env.ts index 4a18604..d764b5a 100644 --- a/anify-backend/src/env.ts +++ b/anify-backend/src/env.ts @@ -1,19 +1,13 @@ // All environment variables. export const env = { PORT: Number(process.env.PORT) || 3000, - DATABASE_TYPE: process.env.DATABASE_TYPE || "postgres", - DATABASE_URL: process.env.DATABASE_URL, NINEANIME_RESOLVER: process.env.NINEANIME_RESOLVER, NINEANIME_KEY: process.env.NINEANIME_KEY, REDIS_URL: process.env.REDIS_URL, REDIS_CACHE_TIME: Number(process.env.REDIS_CACHE_TIME) || 60 * 60 * 24 * 7, - USE_API_KEYS: process.env.USE_API_KEYS || "false", - MASTER_KEY: process.env.MASTER_KEY, - API_KEY_WHITELIST: process.env.API_KEY_WHITELIST?.split(",") || [], CENSYS_ID: process.env.CENSYS_ID, CENSYS_SECRET: process.env.CENSYS_SECRET, SIMKL_CLIENT_ID: process.env.SIMKL_CLIENT_ID, - SIMKL_CLIENT_SECRET: process.env.SIMKL_CLIENT_SECRET, USE_MIXDROP: process.env.USE_MIXDROP === "true" || false, MIXDROP_EMAIL: process.env.MIXDROP_EMAIL, MIXDROP_KEY: process.env.MIXDROP_KEY, diff --git a/anify-backend/src/helper/event.ts b/anify-backend/src/helper/event.ts deleted file mode 100644 index f2c61a2..0000000 --- a/anify-backend/src/helper/event.ts +++ /dev/null @@ -1,14 +0,0 @@ -import EventEmitter2 from "eventemitter2"; - -export enum Events { - COMPLETED_MAPPING_LOAD = "mapping.load.completed", - COMPLETED_SKIPTIMES_LOAD = "skiptimes.load.completed", - COMPLETED_SEARCH_LOAD = "search.load.completed", - COMPLETED_SEASONAL_LOAD = "seasonal.load.completed", - COMPLETED_ENTRY_CREATION = "entry.creation.completed", - COMPLETED_PAGE_UPLOAD = "page.upload.completed", -} - -const emitter = new EventEmitter2({}); - -export default emitter; diff --git a/anify-backend/src/helper/executor.ts b/anify-backend/src/helper/executor.ts deleted file mode 100644 index 3372ae7..0000000 --- a/anify-backend/src/helper/executor.ts +++ /dev/null @@ -1,31 +0,0 @@ -export default class ChunkedExecutor { - private items: T[]; - private chunkSize: number; - private executor: (item: T) => Promise; - private perChunkCallback?: (chunk: T[]) => void; - private perResultCallback?: (result: R[]) => void; - constructor(items: T[], chunkSize: number, executor: (item: T) => Promise, perChunkCallback?: (chunk: T[]) => void, perResultCallback?: (result: R[]) => void) { - this.items = items; - this.chunkSize = chunkSize; - this.executor = executor; - this.perChunkCallback = perChunkCallback; - this.perResultCallback = perResultCallback; - } - - public async execute(): Promise { - const results: R[] = []; - for (let i = 0; i < this.items.length; i += this.chunkSize) { - const chunk = this.items.slice(i, i + this.chunkSize); - if (this.perChunkCallback) { - this.perChunkCallback(chunk); - } - const promises = chunk.map((item) => this.executor(item)); - const chunkResults = await Promise.all(promises); - results.push(...chunkResults.filter((result) => result !== null)); - if (this.perResultCallback) { - this.perResultCallback(results); - } - } - return results; - } -} diff --git a/anify-backend/src/helper/extractor.ts b/anify-backend/src/helper/extractor.ts index 0062ce5..db96a22 100644 --- a/anify-backend/src/helper/extractor.ts +++ b/anify-backend/src/helper/extractor.ts @@ -1,9 +1,9 @@ import CryptoJS from "crypto-js"; import { load } from "cheerio"; -import { isJson, substringAfter, substringBefore } from "."; -import { type Source, StreamingServers } from "../mapping/impl/anime"; -import { animeProviders } from "../mapping"; +import { substringAfter, substringBefore } from "."; import { env } from "process"; +import { Source } from "../types/types"; +import { StreamingServers } from "../types/enums"; export default class Extractor { private url: string; @@ -36,12 +36,6 @@ export default class Extractor { return await this.extractKwik(this.url, this.result); case StreamingServers.AllAnime: return await this.extractAllAnime(this.url, this.result); - case StreamingServers.DuckStream: - return await this.extractDuckStream(this.url, this.result); - case StreamingServers.DuckStreamV2: - return await this.extractDuckStreamV2(this.url, this.result); - case StreamingServers.BirdStream: - return await this.extractBirdStream(this.url, this.result); case StreamingServers.AnimeFlix: return await this.extractAnimeFlix(this.url, this.result); default: @@ -103,7 +97,7 @@ export default class Extractor { try { const subtitles = JSON.parse($.html().split("instance.setTrackByUrl(JSON.parse(`")[1].split("`).find")[0]); - subtitles.map((subtitle) => { + subtitles.map((subtitle: { title: string; lang: string; url: string }) => { result.subtitles.push({ label: subtitle.title, lang: subtitle.lang, @@ -139,7 +133,7 @@ export default class Extractor { const mainReq = await ( await fetch(m3u8File, { - headers: animeProviders["9anime"].headers, + headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, }) ).json(); @@ -154,7 +148,7 @@ export default class Extractor { const file = mainReq.result?.sources[0]?.file; const req = await fetch(file, { - headers: animeProviders["9anime"].headers, + headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, }); const resolutions = (await req.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); @@ -242,7 +236,7 @@ export default class Extractor { const mainReq = await ( await fetch(m3u8File, { - headers: animeProviders["9anime"].headers, + headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, }) ).json(); @@ -257,7 +251,7 @@ export default class Extractor { const file = mainReq.result?.sources[0]?.file; const req = await fetch(file, { - headers: animeProviders["9anime"].headers, + headers: { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }, }); const resolutions = (await req.text()).match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); @@ -360,7 +354,7 @@ export default class Extractor { const decryptedData = CryptoJS.enc.Utf8.stringify( CryptoJS.AES.decrypt(encryptedData, keys.secondKey, { iv: keys.iv, - }) + }), ); return JSON.parse(decryptedData); @@ -412,7 +406,7 @@ export default class Extractor { } } - sources = encryptedURLTemp.filter((x) => x !== null).join(""); + sources = encryptedURLTemp.filter((x: any) => x !== null).join(""); try { sources = JSON.parse(CryptoJS.AES.decrypt(sources, key).toString(CryptoJS.enc.Utf8)); @@ -570,466 +564,4 @@ export default class Extractor { return result; } - - public async extractDuckStream(url: string, result: Source): Promise { - const order = await (await fetch("https://raw.githubusercontent.com/enimax-anime/gogo/main/KAA.json")).json(); - - const data = await (await fetch(url)).text(); - const cid = data.split("cid:")[1].split("'")[1].trim(); - - const metaData = CryptoJS.enc.Hex.parse(cid).toString(CryptoJS.enc.Utf8); - const sigArray: any[] = []; - - let key = ""; - - try { - const res = await fetch("https://raw.githubusercontent.com/enimax-anime/kaas/duck/key.txt"); - if (res.status === 404) { - throw new Error("Not found"); - } else { - key = await res.text(); - } - } catch { - key = await (await fetch("https://raw.githubusercontent.com/enimax-anime/kaas/duck/key.txt")).json(); - } - - const signatureItems = { - SIG: data.split("signature:")[1].split("'")[1].trim(), - USERAGENT: "Mozilla/5.0 (Linux; Android 10; SM-A415F Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/96.0.4664.104 Mobile Safari/537.36 [FB_IAB/Orca-Android;FBAV/341.0.0.6.237;]", - IP: metaData.split("|")[0], - ROUTE: metaData.split("|")[1].replace("player.php", "source.php"), - KEY: key, - TIMESTAMP: Math.floor(Date.now() / 1000), - MID: new URL(url).searchParams.get("mid"), - }; - - for (const item of order.duck) { - sigArray.push(signatureItems[item]); - } - - const sig = CryptoJS.SHA1(sigArray.join("")).toString(CryptoJS.enc.Hex); - - const res = ( - await ( - await fetch(`${new URL(url).origin}${signatureItems.ROUTE}?${"mid"}=${signatureItems.MID}${"&e=" + signatureItems.TIMESTAMP}&s=${sig}`, { - headers: { - Referer: `${new URL(url).origin}${signatureItems.ROUTE.replace("source.php", "player.php")}?${"mid"}=${signatureItems.MID}`, - "User-Agent": signatureItems.USERAGENT, - }, - }) - ).json() - ).data; - - const finalResult = JSON.parse( - CryptoJS.AES.decrypt(res.split(":")[0], CryptoJS.enc.Utf8.parse(signatureItems.KEY), { - mode: CryptoJS.mode.CBC, - iv: CryptoJS.enc.Hex.parse(res.split(":")[1]), - keySize: 256, - }).toString(CryptoJS.enc.Utf8) - ); - - let hlsURL = "", - dashURL = ""; - - if (finalResult.hls) { - hlsURL = finalResult.hls.startsWith("//") ? `https:${finalResult.hls}` : finalResult.hls; - - result.sources.push({ - quality: "auto", - url: hlsURL, - }); - - try { - const data = await (await fetch(hlsURL)).text(); - - // Extract qualities - const resolutions = data.match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - - resolutions?.forEach((res: string) => { - const index = hlsURL.lastIndexOf("/"); - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - const url = new URL(hlsURL.slice(0, index)).origin; - - result.sources.push({ - url: url + (res.split("\n")[1]?.startsWith("/") ? "" : "/") + res.split("\n")[1], - quality: quality + "p", - }); - }); - - // Extract audio - const audioRegex = /#EXT-X-MEDIA:TYPE=AUDIO,.*URI="(.*)"/g; - const audioMatches = [...data.matchAll(audioRegex)]; - - audioMatches?.forEach((value: RegExpMatchArray, i: number, array: RegExpMatchArray[]) => { - const audioUrl = value[1]; - const index = hlsURL.lastIndexOf("/"); - const nameMatch = value[0].match(/NAME="([^"]*)"/); - const languageMatch = value[0].match(/LANGUAGE="([^"]*)"/); - - if (nameMatch && languageMatch) { - const name = nameMatch[1]; - const language = languageMatch[1]; - const url = hlsURL.slice(0, index); - - result.audio.push({ - name: name, - language: language, - url: url + "/" + audioUrl, - }); - } - }); - } catch (e) { - // - } - - result.intro.start = finalResult.skip?.intro?.start ?? 0; - result.intro.end = finalResult.skip?.intro?.end ?? 0; - } - - if (finalResult.dash) { - dashURL = finalResult.dash.startsWith("//") ? `https:${finalResult.dash}` : finalResult.dash; - - result.sources.push({ - quality: "dash", - url: dashURL, - }); - - result.intro.start = finalResult.skip?.intro?.start ?? 0; - result.intro.end = finalResult.skip?.intro?.end ?? 0; - } - - if (finalResult.subtitles) { - if (hlsURL.length > 0) { - finalResult.subtitles.map((sub) => { - result.subtitles.push({ - label: `${sub.name}`, - url: sub.src.startsWith("//") ? `https:${sub.src}` : new URL(sub.src, hlsURL).href, - lang: sub.language, - }); - }); - } - - if (dashURL.length > 0 && finalResult.subtitles.length === 0) { - finalResult.subtitles.map((sub) => { - result.subtitles.push({ - label: `${sub.name}`, - url: sub.src.startsWith("//") ? `https:${sub.src}` : new URL(sub.src, dashURL).href, - lang: sub.language, - }); - }); - } - } - - return result; - } - - public async extractDuckStreamV2(url: string, result: Source): Promise { - const order = await (await fetch("https://raw.githubusercontent.com/enimax-anime/gogo/main/KAA.json")).json(); - - const data = await (await fetch(url)).text(); - const cid = data.split("cid:")[1].split("'")[1].trim(); - - const metaData = CryptoJS.enc.Hex.parse(cid).toString(CryptoJS.enc.Utf8); - const sigArray: any[] = []; - - let key = ""; - - try { - const res = await fetch("https://raw.githubusercontent.com/enimax-anime/kaas/duck/key.txt"); - if (res.status === 404) { - throw new Error("Not found"); - } else { - key = await res.text(); - } - } catch { - key = await (await fetch("https://raw.githubusercontent.com/enimax-anime/kaas/duck/key.txt")).json(); - } - - const signatureItems = { - SIG: data.split("signature:")[1].split("'")[1].trim(), - USERAGENT: "Mozilla/5.0 (Linux; Android 10; SM-A415F Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/96.0.4664.104 Mobile Safari/537.36 [FB_IAB/Orca-Android;FBAV/341.0.0.6.237;]", - IP: metaData.split("|")[0], - ROUTE: metaData.split("|")[1].replace("player.php", "source.php"), - KEY: key, - TIMESTAMP: Math.floor(Date.now() / 1000), - MID: new URL(url).searchParams.get("id"), - }; - - for (const item of order.duck) { - sigArray.push(signatureItems[item]); - } - - const sig = CryptoJS.SHA1(sigArray.join("")).toString(CryptoJS.enc.Hex); - - const res = ( - await ( - await fetch(`${new URL(url).origin}${signatureItems.ROUTE}?${"id"}=${signatureItems.MID}${"&e=" + signatureItems.TIMESTAMP}&s=${sig}`, { - headers: { - Referer: `${new URL(url).origin}${signatureItems.ROUTE.replace("source.php", "player.php")}?${"mid"}=${signatureItems.MID}`, - "User-Agent": signatureItems.USERAGENT, - }, - }) - ).json() - ).data; - - const finalResult = JSON.parse( - CryptoJS.AES.decrypt(res.split(":")[0], CryptoJS.enc.Utf8.parse(signatureItems.KEY), { - mode: CryptoJS.mode.CBC, - iv: CryptoJS.enc.Hex.parse(res.split(":")[1]), - keySize: 256, - }).toString(CryptoJS.enc.Utf8) - ); - - let hlsURL = "", - dashURL = ""; - - if (finalResult.hls) { - hlsURL = finalResult.hls.startsWith("//") ? `https:${finalResult.hls}` : finalResult.hls; - - result.sources.push({ - quality: "auto", - url: hlsURL, - }); - - try { - const data = await (await fetch(hlsURL)).text(); - - // Extract qualities - const resolutions = data.match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - - resolutions?.forEach((res: string) => { - const index = hlsURL.lastIndexOf("/"); - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - const url = new URL(hlsURL.slice(0, index)).origin; - - result.sources.push({ - url: url + (res.split("\n")[1]?.startsWith("/") ? "" : "/") + res.split("\n")[1], - quality: quality + "p", - }); - }); - - // Extract audio - const audioRegex = /#EXT-X-MEDIA:TYPE=AUDIO,.*URI="(.*)"/g; - const audioMatches = [...data.matchAll(audioRegex)]; - - audioMatches?.forEach((value: RegExpMatchArray, i: number, array: RegExpMatchArray[]) => { - const audioUrl = value[1]; - const index = hlsURL.lastIndexOf("/"); - const nameMatch = value[0].match(/NAME="([^"]*)"/); - const languageMatch = value[0].match(/LANGUAGE="([^"]*)"/); - - if (nameMatch && languageMatch) { - const name = nameMatch[1]; - const language = languageMatch[1]; - const url = hlsURL.slice(0, index); - - result.audio.push({ - name: name, - language: language, - url: url + "/" + audioUrl, - }); - } - }); - } catch (e) { - // - } - - result.intro.start = finalResult.skip?.intro?.start ?? 0; - result.intro.end = finalResult.skip?.intro?.end ?? 0; - } - - if (finalResult.dash) { - dashURL = finalResult.dash.startsWith("//") ? `https:${finalResult.dash}` : finalResult.dash; - - result.sources.push({ - quality: "dash", - url: dashURL, - }); - - result.intro.start = finalResult.skip?.intro?.start ?? 0; - result.intro.end = finalResult.skip?.intro?.end ?? 0; - } - - if (finalResult.subtitles) { - if (hlsURL.length > 0) { - finalResult.subtitles.map((sub) => { - result.subtitles.push({ - label: `${sub.name}`, - url: sub.src.startsWith("//") ? `https:${sub.src}` : new URL(sub.src, hlsURL).href, - lang: sub.language, - }); - }); - } - - if (dashURL.length > 0 && finalResult.subtitles.length === 0) { - finalResult.subtitles.map((sub) => { - result.subtitles.push({ - label: `${sub.name}`, - url: sub.src.startsWith("//") ? `https:${sub.src}` : new URL(sub.src, dashURL).href, - lang: sub.language, - }); - }); - } - } - - return result; - } - - public async extractBirdStream(url: string, result: Source): Promise { - const order = await (await fetch("https://raw.githubusercontent.com/enimax-anime/gogo/main/KAA.json")).json(); - - const data = await (await fetch(url)).text(); - const cid = data.split("cid:")[1].split("'")[1].trim(); - - const metaData = CryptoJS.enc.Hex.parse(cid).toString(CryptoJS.enc.Utf8); - const sigArray: any[] = []; - - let key = ""; - - try { - const res = await fetch("https://raw.githubusercontent.com/enimax-anime/kaas/bird/key.txt"); - if (res.status === 404) { - throw new Error("Not found"); - } else { - key = await res.text(); - } - } catch { - key = await (await fetch("https://raw.githubusercontent.com/enimax-anime/kaas/bird/key.txt")).json(); - } - - const signatureItems = { - SIG: data.split("signature:")[1].split("'")[1].trim(), - USERAGENT: "Mozilla/5.0 (Linux; Android 10; SM-A415F Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/96.0.4664.104 Mobile Safari/537.36 [FB_IAB/Orca-Android;FBAV/341.0.0.6.237;]", - IP: metaData.split("|")[0], - ROUTE: metaData.split("|")[1].replace("player.php", "source.php"), - KEY: key, - TIMESTAMP: Math.floor(Date.now() / 1000), - MID: new URL(url).searchParams.get("id"), - }; - - for (const item of order.bird) { - sigArray.push(signatureItems[item]); - } - - const sig = CryptoJS.SHA1(sigArray.join("")).toString(CryptoJS.enc.Hex); - - const res = ( - await ( - await fetch(`${new URL(url).origin}${signatureItems.ROUTE}?${"id"}=${signatureItems.MID}&s=${sig}`, { - headers: { - Referer: `${new URL(url).origin}${signatureItems.ROUTE.replace("source.php", "player.php")}?${"id"}=${signatureItems.MID}`, - "User-Agent": signatureItems.USERAGENT, - }, - }) - ).json() - ).data; - - const finalResult = JSON.parse( - CryptoJS.AES.decrypt(res.split(":")[0], CryptoJS.enc.Utf8.parse(signatureItems.KEY), { - mode: CryptoJS.mode.CBC, - iv: CryptoJS.enc.Hex.parse(res.split(":")[1]), - keySize: 256, - }).toString(CryptoJS.enc.Utf8) - ); - - let hlsURL = "", - dashURL = ""; - - if (finalResult.hls) { - hlsURL = finalResult.hls.startsWith("//") ? `https:${finalResult.hls}` : finalResult.hls; - - result.sources.push({ - quality: "auto", - url: hlsURL, - }); - - try { - const data = await (await fetch(hlsURL)).text(); - - // Extract qualities - const resolutions = data.match(/(RESOLUTION=)(.*)(\s*?)(\s*.*)/g); - - resolutions?.forEach((res: string) => { - const index = hlsURL.lastIndexOf("/"); - const quality = res.split("\n")[0].split("x")[1].split(",")[0]; - const url = new URL(hlsURL.slice(0, index)).origin; - - result.sources.push({ - url: url + (res.split("\n")[1]?.startsWith("/") ? "" : "/") + res.split("\n")[1], - quality: quality + "p", - }); - }); - - // Extract audio - const audioRegex = /#EXT-X-MEDIA:TYPE=AUDIO,.*URI="(.*)"/g; - const audioMatches = [...data.matchAll(audioRegex)]; - - audioMatches?.forEach((value: RegExpMatchArray, i: number, array: RegExpMatchArray[]) => { - const audioUrl = value[1]; - const index = hlsURL.lastIndexOf("/"); - const nameMatch = value[0].match(/NAME="([^"]*)"/); - const languageMatch = value[0].match(/LANGUAGE="([^"]*)"/); - - if (nameMatch && languageMatch) { - const name = nameMatch[1]; - const language = languageMatch[1]; - const url = hlsURL.slice(0, index); - - result.audio.push({ - name: name, - language: language, - url: url + "/" + audioUrl, - }); - } - }); - } catch (e) { - // - } - - result.intro.start = finalResult.cues?.intro?.start_ms ?? 0; - result.intro.end = finalResult.cues?.intro?.end_ms ?? 0; - - result.outro.start = finalResult.cues?.ending?.start_ms ?? 0; - result.outro.end = finalResult.cues?.ending?.end_ms ?? 0; - } - - if (finalResult.dash) { - dashURL = finalResult.dash.startsWith("//") ? `https:${finalResult.dash}` : finalResult.dash; - - result.sources.push({ - quality: "dash", - url: dashURL, - }); - - result.intro.start = finalResult.cues?.intro?.start_ms ?? 0; - result.intro.end = finalResult.cues?.intro?.end_ms ?? 0; - - result.outro.start = finalResult.cues?.ending?.start_ms ?? 0; - result.outro.end = finalResult.cues?.ending?.end_ms ?? 0; - } - - if (finalResult.subtitles) { - if (hlsURL.length > 0) { - finalResult.subtitles.map((sub) => { - result.subtitles.push({ - label: `${sub.name}`, - url: sub.src.startsWith("//") ? `https:${sub.src}` : new URL(sub.src, hlsURL).href, - lang: sub.language, - }); - }); - } - - if (dashURL.length > 0 && finalResult.subtitles.length === 0) { - finalResult.subtitles.map((sub) => { - result.subtitles.push({ - label: `${sub.name}`, - url: sub.src.startsWith("//") ? `https:${sub.src}` : new URL(sub.src, dashURL).href, - lang: sub.language, - }); - }); - } - } - - return result; - } } diff --git a/anify-backend/src/helper/generator/index.ts b/anify-backend/src/helper/generator/index.ts deleted file mode 100644 index 42cdac9..0000000 --- a/anify-backend/src/helper/generator/index.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { Genres } from "../../mapping"; - -export function anilistMediaGenerator(data: any) { - return { - aniListId: data.id, - malId: data.idMal, - title: { - english: data.title.english ?? null, - romaji: data.title.romaji ?? null, - native: data.title.native ?? null, - }, - coverImage: data.coverImage.extraLarge ?? null, - bannerImage: data.bannerImage ?? null, - popularity: Number(data.popularity), - synonyms: data.synonyms ?? [], - totalChapters: data.chapters ?? 0, - totalVolumes: data.volumes ?? 0, - color: null, - status: data.status, - genres: (data.genres as Genres[]) ?? [], - rating: data.meanScore ? data.meanScore / 10 : null, - description: data.description ?? null, - format: data.format, - countryOfOrigin: data.countryOfOrigin ?? null, - year: data.seasonYear ?? data.startDate?.year ?? null, - type: data.type, - tags: data.tags.map((tag: { name: string }) => tag.name), - }; -} - -export function generateQueryBuilder(id: string) { - return ` - anime${id}:Page(page: 0, perPage: 10){ - media(id:${id}){ - id - idMal - title { - romaji - english - native - userPreferred - } - coverImage { - extraLarge - large - color - } - bannerImage - startDate { - year - month - day - } - endDate { - year - month - day - } - description - season - seasonYear - type - format - status(version: 2) - episodes - duration - chapters - volumes - genres - synonyms - source(version: 3) - isAdult - meanScore - averageScore - popularity - favourites - countryOfOrigin - isLicensed - relations { - edges { - id - relationType(version: 2) - node { - id - title { - userPreferred - } - format - type - status(version: 2) - bannerImage - coverImage { - large - } - } - } - } - streamingEpisodes { - title - thumbnail - url - } - trailer { - id - site - } - tags { - id - name - } - } - } - `; -} diff --git a/anify-backend/src/helper/index.ts b/anify-backend/src/helper/index.ts index 3797ae1..88ec080 100644 --- a/anify-backend/src/helper/index.ts +++ b/anify-backend/src/helper/index.ts @@ -1,22 +1,9 @@ -import { compareTwoStrings } from "./stringSimilarity"; - -export const USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"; - export function wait(time: number) { return new Promise((resolve) => { setTimeout(resolve, time); }); } -export function isJson(str: string) { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; -} - export function substringBefore(str: string, toFind: string) { const index = str.indexOf(toFind); return index == -1 ? "" : str.substring(0, index); @@ -27,52 +14,8 @@ export function substringAfter(str: string, toFind: string) { return index == -1 ? "" : str.substring(index + toFind.length); } -export function sanitizeTitle(title: string): string { - let resTitle = title.replace(/ *(\(dub\)|\(sub\)|\(uncensored\)|\(uncut\)|\(subbed\)|\(dubbed\))/i, ""); - resTitle = resTitle.replace(/ *\([^)]+audio\)/i, ""); - resTitle = resTitle.replace(/ BD( |$)/i, ""); - resTitle = resTitle.replace(/\(TV\)/g, ""); - resTitle = resTitle.trim(); - resTitle = resTitle.substring(0, 99); // truncate - return resTitle; -} - -export function similarity(externalTitle: string, title: string, titleArray: string[] = []): { same: boolean; value: number } { - if (!title) { - title = ""; - } - let simi = compareTwoStrings(sanitizeTitle(title.toLowerCase()), externalTitle.toLowerCase()); - titleArray.forEach((el) => { - if (el) { - const tempSimi = compareTwoStrings(title.toLowerCase(), el.toLowerCase()); - if (tempSimi > simi) simi = tempSimi; - } - }); - let found = false; - if (simi > 0.6) { - found = true; - } - - return { - same: found, - value: simi, - }; -} - -export function stringSearch(string: string, pattern: string): number { - let count = 0; - string = string.toLowerCase(); - pattern = pattern.toLowerCase(); - string = string.replace(/[^a-zA-Z0-9 -]/g, ""); - pattern = pattern.replace(/[^a-zA-Z0-9 -]/g, ""); - - for (let i = 0; i < string.length; i++) { - for (let j = 0; j < pattern.length; j++) { - if (pattern[j] !== string[i + j]) break; - if (j === pattern.length - 1) count++; - } - } - return count; +export function isString(object: unknown): object is string { + return typeof object === "string"; } export function setIntervalImmediately(func: () => Promise, interval: number) { @@ -86,76 +29,17 @@ export function setIntervalImmediately(func: () => Promise, interval: numb }, interval); } -export const slugify = (...args: (string | number)[]): string => { - const replaceLoweringCase = (string: string, [regExp, replacement]: any) => string.replace(RegExp(regExp, "giu"), replacement); +export const averageMetric = (object: any) => { + let average = 0, + validCount = 0; + if (!object) return 0; - let value = args.join(" "); - - defaultReplacements.forEach(([a, b]) => { - value = replaceLoweringCase(value, [a, b]); - }); + for (const [_, v] of Object.entries(object)) { + if (v && typeof v === "number") { + average += v; + validCount++; + } + } - return value - .normalize("NFD") - .replace(/[\u0300-\u036f]/g, "-") - .toLowerCase() - .trim() - .replace(/[^a-z0-9 ]/g, "-") - .replace(/\s+/g, "-"); + return validCount === 0 ? 0 : Number.parseFloat((average / validCount).toFixed(2)); }; - -const defaultReplacements = [ - ["[aàáâãäåāăąǻάαа]", "a"], - ["[bбḃ]", "b"], - ["[cçćĉċčћ]", "c"], - ["[dðďđδдђḋ]", "d"], - ["[eèéêëēĕėęěέεеэѐё]", "e"], - ["[fƒφфḟ]", "f"], - ["[gĝğġģγгѓґ]", "g"], - ["[hĥħ]", "h"], - ["[iìíîïĩīĭįıΐήίηιϊийіїѝ]", "i"], - ["[jĵј]", "j"], - ["[kķĸκкќ]", "k"], - ["[lĺļľŀłλл]", "l"], - ["[mμмṁ]", "m"], - ["[nñńņňʼnŋνн]", "n"], - ["[oòóôõöōŏőοωόώо]", "o"], - ["[pπпṗ]", "p"], - ["q", "q"], - ["[rŕŗřρр]", "r"], - ["[sśŝşšſșςσсṡ]", "s"], - ["[tţťŧțτтṫ]", "t"], - ["[uùúûüũūŭůűųуў]", "u"], - ["[vβв]", "v"], - ["[wŵẁẃẅ]", "w"], - ["[xξ]", "x"], - ["[yýÿŷΰυϋύыỳ]", "y"], - ["[zźżžζз]", "z"], - ["[æǽ]", "ae"], - ["[χч]", "ch"], - ["[ѕџ]", "dz"], - ["fi", "fi"], - ["fl", "fl"], - ["я", "ia"], - ["[ъє]", "ie"], - ["ij", "ij"], - ["ю", "iu"], - ["х", "kh"], - ["љ", "lj"], - ["њ", "nj"], - ["[øœǿ]", "oe"], - ["ψ", "ps"], - ["ш", "sh"], - ["щ", "shch"], - ["ß", "ss"], - ["[þθ]", "th"], - ["ц", "ts"], - ["ж", "zh"], - - // White_Space, General_Category=Dash_Punctuation and Control Codes - ["[\\u0009-\\u000D\\u001C-\\u001F\\u0020\\u002D\\u0085\\u00A0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000\\u058A\\u05BE\\u1400\\u1806\\u2010-\\u2015\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D]", "-"], -]; - -export function isString(object: unknown): object is string { - return typeof object === "string"; -} diff --git a/anify-backend/src/helper/proxies/goodProxies.json b/anify-backend/src/helper/proxies/goodProxies.json deleted file mode 100644 index ffe7935..0000000 --- a/anify-backend/src/helper/proxies/goodProxies.json +++ /dev/null @@ -1,6105 +0,0 @@ -[ - "189.111.202.183:5050", - "180.150.79.23:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000", - "189.111.202.183:5050", - "180.150.79.23:5000", - "190.252.224.109:8002", - "47.106.95.141:8866", - "162.241.41.45:3000", - "43.134.46.175:5210", - "52.149.157.55:3000", - "200.170.211.118:9999", - "34.126.141.53:8090", - "134.102.219.4:9090", - "162.241.129.193:3000", - "177.25.63.58:9999", - "46.36.218.98:4000", - "81.30.80.124:12000", - "35.247.147.119:8090", - "213.203.179.36:8008", - "174.136.135.59:2000", - "189.8.93.93:9999", - "134.249.176.139:3004", - "176.111.61.59:4044", - "217.25.94.184:8090", - "191.185.163.152:8099", - "34.89.42.44:5017", - "200.91.201.186:8002", - "200.155.185.180:9999", - "120.24.58.145:9001", - "82.213.209.149:8081", - "35.241.97.229:5000", - "200.49.47.234:9999", - "43.135.76.33:36543", - "119.195.193.112:8081", - "89.22.114.39:7000", - "47.75.97.125:9988", - "34.87.69.7:8090", - "46.4.59.216:81", - "122.52.135.214:3000", - "50.83.117.177:8088", - "20.51.249.171:8082", - "174.136.150.112:2000" -] \ No newline at end of file diff --git a/anify-backend/src/helper/proxies/index.ts b/anify-backend/src/helper/proxies/index.ts deleted file mode 100644 index ee87ad1..0000000 --- a/anify-backend/src/helper/proxies/index.ts +++ /dev/null @@ -1,383 +0,0 @@ -import colors from "colors"; -import { existsSync, writeFileSync } from "fs"; -import { readFile, writeFile } from "fs/promises"; -import { join } from "path"; -import ChunkedExecutor from "../executor"; -import cluster from "node:cluster"; -import { isString } from ".."; -import { ANIME_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS } from "../../mapping"; -import { env } from "../../env"; - -// List of CORS proxies -export const CORS_PROXIES: string[] = []; -const toCheck: string[] = []; - -export async function fetchCorsProxies(): Promise { - if (existsSync(join(__dirname, "./goodProxies.json"))) { - const BATCH_SIZE = 100; - - const fileContents = await readFile(join(__dirname, "./goodProxies.json"), "utf-8"); - const proxyData = JSON.parse(fileContents); - const totalProxies = proxyData.length; - let currentIndex = 0; - - while (currentIndex < totalProxies) { - const proxiesToAdd: string[] = []; - - for (let i = 0; i < BATCH_SIZE && currentIndex < totalProxies; i++, currentIndex++) { - const proxy = proxyData[currentIndex]; - - if (!proxy.startsWith("http")) { - proxiesToAdd.push(`http://${proxy}`); - } else { - proxiesToAdd.push(proxy); - } - } - - if (cluster.isPrimary) console.log(colors.yellow(`Adding ${proxiesToAdd.length} proxies to the list.`)); - - CORS_PROXIES.push(...proxiesToAdd); - } - - if (cluster.isPrimary) console.log(colors.green("Finished importing proxies.")); - } else { - return []; - } - return CORS_PROXIES; -} - -export async function scrapeCorsProxies(): Promise { - const hits: { ip: string; port: number }[] = []; - let cursor: any = null; // Initialize cursor as null - const maxRequests = 50; - let currentRequest = 0; - - console.log(colors.yellow("Searching for proxies on Censys...")); - - try { - do { - const data = await search("c7d96235df80ea051e9d57f3ab6d3e4da289fd3b", cursor); - if (!data) { - break; - } - - data.result.hits.filter((hit) => { - hit.services.some((service) => { - if (service.extended_service_name === "HTTP" || service.extended_service_name === "HTTPS") { - hits.push({ ip: hit.ip, port: service.port }); - } - }); - }); - - console.log(colors.gray("Fetched ") + colors.blue(hits.length + "") + colors.gray(" hits so far.")); - - cursor = data.result.links.next; - currentRequest++; - - // Break the loop if cursor is null or empty string, or maxRequests limit is reached - if (cursor === null || cursor === "" || currentRequest >= maxRequests) { - console.log(colors.gray("Finished fetching proxies from Censys.")); - - await writeFile(join(__dirname, "./proxies.json"), JSON.stringify(hits, null, 4)); - toCheck.push(...hits.map((hit) => `http://${hit.ip}:${hit.port}`)); - - await checkCorsProxies(); - break; - } - } while (cursor !== null && cursor !== "" && currentRequest < maxRequests); - } catch (error) { - // Handle the error if necessary - console.error(error); - } -} - -export async function checkCorsProxies(): Promise { - const goodIps: string[] = []; - console.log(colors.yellow("Importing proxies... Please note that reading the proxies file may take a while.")); - if (toCheck.length === 0) { - if (existsSync(join(__dirname, "./proxies.json"))) { - // Check proxies.json - const proxies = await readFile(join(__dirname, "./proxies.json"), "utf-8"); - if (proxies) { - for (let i = 0; i < JSON.parse(proxies).length; i++) { - const ip = JSON.parse(proxies)[i].ip; - const port = JSON.parse(proxies)[i].port; - - const url = `http://${ip}:${port}`; - toCheck.push(url); - } - } - console.log(colors.green("Finished importing current proxies.")); - } - } - console.log(colors.yellow("Checking proxies...")); - const ips = toCheck - .map((proxy) => { - try { - const url = new URL(proxy); - return { ip: url.hostname, port: Number(url.port) }; - } catch (e) { - return { ip: "", port: 8080 }; - } - }) - .filter((obj) => obj.port != 8080); - - const chunkSize = 25; - const perChunkCallback = (chunk: IP[]) => { - console.log(colors.gray(`Checking ${chunk.length} proxies...`)); - }; - - const perResultsCallback = (result: (string | undefined)[]) => { - const ips = result.filter(isString); - goodIps.push(...ips); - console.log(colors.green(`${ips.length} proxies are good!`)); - writeFileSync(join(__dirname, "./goodProxies.json"), JSON.stringify(goodIps, null, 4)); - }; - - const executor = new ChunkedExecutor(ips, chunkSize, makeRequest, perChunkCallback, perResultsCallback); - await executor.execute(); - - console.log(colors.gray("Finished checking proxies.")); - - CORS_PROXIES.length = 0; - toCheck.length = 0; - CORS_PROXIES.push(...goodIps); - return goodIps; -} - -async function search(q: string, cursor: string | null = null): Promise { - const appendCursor = cursor ? `&cursor=${cursor}` : ""; - - const url = "/hosts/search?q=" + q + `&per_page=100&virtual_hosts=EXCLUDE` + appendCursor; - - if (!env.CENSYS_ID || !env.CENSYS_SECRET) { - console.log(colors.yellow("CENSYS_ID or CENSYS_SECRET not found in .env file. Please add them to scrape CORS proxies.")); - return undefined; - } - - const apiID = env.CENSYS_ID ?? "d973cf60-4ce4-4746-962b-815ddfdebf80", - apiSecret = env.CENSYS_SECRET ?? "s6EUuA4Sfaajd8jDBJ17b4DaoPofjDe6"; - - const auth = "Basic " + Buffer.from(apiID + ":" + apiSecret).toString("base64"); - const headers = { Authorization: auth }; - - const data = await ( - await fetch(`https://search.censys.io/api/v2${url}`, { - headers: headers, - }) - ).json(); - return data; -} - -async function makeRequest(ip: IP): Promise { - const timeout = 3000; - const controller = new AbortController(); - const id = setTimeout(() => controller.abort(), timeout); - - try { - const response = await fetch(`http://${ip.ip}:${ip.port}/iscorsneeded`, { - signal: controller.signal, - }); - if (response.status === 200 && (await response.text()) === "no") { - const secondResponse = await fetch(`http://${ip.ip}:${ip.port}/https://graphql.anilist.co`, { - signal: controller.signal, - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - Origin: "graphql.anilist.co", - }, - body: JSON.stringify({ - query: `query ($id: Int) { - Media (id: $id) { - id - title { - romaji - english - native - } - } - }`, - variables: { - id: 21, - }, - }), - }).catch((err) => { - return null; - }); - - clearTimeout(id); - if (secondResponse?.ok) { - let text: any = undefined; - - try { - text = await secondResponse.json(); - } catch (e) { - console.log(colors.red(`Error parsing JSON from ${ip.ip}:${ip.port}: ${e}`)); - } - - if (!text) { - return undefined; - } - - let isOkay = true; - - for (const provider of ANIME_PROVIDERS) { - console.log(colors.gray("Testing ") + provider.id + colors.gray(".")); - - provider.customProxy = `http://${ip.ip}:${ip.port}`; - - const providerResponse = await provider.search("Mushoku Tensei").catch((err) => { - return undefined; - }); - - if (!providerResponse) { - console.log(colors.red(`${provider.id} failed.`)); - isOkay = false; - provider.customProxy = undefined; - break; - } - - provider.customProxy = undefined; - } - - if (isOkay) { - console.log(colors.yellow("Anime providers passed.")); - } else { - console.log(colors.red("Anime providers failed.")); - return undefined; - } - - for (const provider of MANGA_PROVIDERS) { - console.log(colors.gray("Testing ") + provider.id + colors.gray(".")); - - provider.customProxy = `http://${ip.ip}:${ip.port}`; - - const providerResponse = await provider.search("Mushoku Tensei").catch((err) => { - return undefined; - }); - - if (!providerResponse) { - isOkay = false; - provider.customProxy = undefined; - break; - } - - provider.customProxy = undefined; - } - - if (isOkay) { - console.log(colors.yellow("Manga providers passed.")); - } else { - console.log(colors.red("Manga providers failed.")); - return undefined; - } - - for (const provider of META_PROVIDERS) { - console.log(colors.gray("Testing ") + provider.id + colors.gray(".")); - - provider.customProxy = `http://${ip.ip}:${ip.port}`; - - const providerResponse = await provider.search("Mushoku Tensei").catch((err) => { - return undefined; - }); - - if (!providerResponse) { - isOkay = false; - provider.customProxy = undefined; - break; - } - - provider.customProxy = undefined; - } - - if (isOkay) { - console.log(colors.yellow("Meta providers passed.")); - return ip.ip + ":" + ip.port; - } else { - console.log(colors.red("Meta providers failed.")); - return undefined; - } - } else { - return undefined; - } - } else { - return undefined; - } - } catch (error) { - return undefined; - } -} - -interface Root { - code: number; - status: string; - result: Result; -} - -interface Result { - query: string; - total: number; - duration: number; - hits: Hit[]; - links: Links; -} - -interface Hit { - ip: string; - services: Service[]; - location: Location; - autonomous_system: AutonomousSystem; - last_updated_at: string; - dns?: Dns; -} - -interface Service { - port: number; - service_name: string; - extended_service_name: string; - transport_protocol: string; - certificate?: string; -} - -interface Location { - continent: string; - country: string; - country_code: string; - city: string; - postal_code?: string; - timezone: string; - coordinates: Coordinates; - province?: string; -} - -interface Coordinates { - latitude: number; - longitude: number; -} - -interface AutonomousSystem { - asn: number; - description: string; - bgp_prefix: string; - name: string; - country_code: string; -} - -interface Dns { - reverse_dns: ReverseDns; -} - -interface ReverseDns { - names: string[]; -} - -interface Links { - next: string; - prev: string; -} - -interface IP { - ip: string; - port: number; -} diff --git a/anify-backend/src/helper/proxies/info.d.ts b/anify-backend/src/helper/proxies/info.d.ts deleted file mode 100644 index 27ea6bf..0000000 --- a/anify-backend/src/helper/proxies/info.d.ts +++ /dev/null @@ -1,339 +0,0 @@ -export interface Info { - code: number; - status: string; - result: Result; -} - -export interface Result { - ip: string; - services: Service[]; - location: Location; - location_updated_at: string; - autonomous_system: AutonomousSystem; - autonomous_system_updated_at: string; - dns: Dns; - last_updated_at: string; - labels: string[]; -} - -export interface Service { - _decoded: string; - _encoding: Encoding; - banner: string; - banner_hashes: string[]; - banner_hex: string; - extended_service_name: string; - labels?: string[]; - observed_at: string; - perspective_id: string; - port: number; - service_name: string; - software?: Software[]; - source_ip: string; - ssh?: Ssh; - transport_fingerprint?: TransportFingerprint; - transport_protocol: string; - truncated: boolean; - certificate?: string; - http?: Http; - jarm?: Jarm; - tls?: Tls; -} - -export interface Encoding { - banner: string; - banner_hex: string; - certificate?: string; -} - -export interface Software { - uniform_resource_identifier: string; - part: string; - vendor: string; - product: string; - source: string; - version?: string; - other?: Other; -} - -export interface Other { - family: string; -} - -export interface Ssh { - endpoint_id: EndpointId; - kex_init_message: KexInitMessage; - algorithm_selection: AlgorithmSelection; - server_host_key: ServerHostKey; - hassh_fingerprint: string; -} - -export interface EndpointId { - _encoding: Encoding2; - raw: string; - protocol_version: string; - software_version: string; -} - -export interface Encoding2 { - raw: string; -} - -export interface KexInitMessage { - kex_algorithms: string[]; - host_key_algorithms: string[]; - client_to_server_ciphers: string[]; - server_to_client_ciphers: string[]; - client_to_server_macs: string[]; - server_to_client_macs: string[]; - client_to_server_compression: string[]; - server_to_client_compression: string[]; - first_kex_follows: boolean; -} - -export interface AlgorithmSelection { - kex_algorithm: string; - host_key_algorithm: string; - client_to_server_alg_group: ClientToServerAlgGroup; - server_to_client_alg_group: ServerToClientAlgGroup; -} - -export interface ClientToServerAlgGroup { - cipher: string; - mac: string; - compression: string; -} - -export interface ServerToClientAlgGroup { - cipher: string; - mac: string; - compression: string; -} - -export interface ServerHostKey { - fingerprint_sha256: string; - ecdsa_public_key: EcdsaPublicKey; -} - -export interface EcdsaPublicKey { - _encoding: Encoding3; - b: string; - curve: string; - gx: string; - gy: string; - length: number; - n: string; - p: string; - x: string; - y: string; -} - -export interface Encoding3 { - b: string; - gx: string; - gy: string; - n: string; - p: string; - x: string; - y: string; -} - -export interface TransportFingerprint { - raw: string; -} - -export interface Http { - request: Request; - response: Response; - supports_http2: boolean; -} - -export interface Request { - method: string; - uri: string; - headers: Headers; -} - -export interface Headers { - Accept: string[]; - _encoding: Encoding4; - User_Agent: string[]; -} - -export interface Encoding4 { - Accept: string; - User_Agent: string; -} - -export interface Response { - protocol: string; - status_code: number; - status_reason: string; - headers: Headers2; - _encoding: Encoding6; - html_tags?: string[]; - body_size: number; - body: string; - favicons?: Favicon[]; - body_hashes: string[]; - body_hash: string; - html_title?: string; -} - -export interface Headers2 { - X_Powered_By?: string[]; - _encoding: Encoding5; - Date: string[]; - Cache_Control?: string[]; - Connection: string[]; - Content_Type?: string[]; - Etag?: string[]; - Keep_Alive: string[]; - Vary?: string[]; - Content_Length?: string[]; -} - -export interface Encoding5 { - X_Powered_By?: string; - Date: string; - Cache_Control?: string; - Connection: string; - Content_Type?: string; - Etag?: string; - Keep_Alive: string; - Vary?: string; - Content_Length?: string; -} - -export interface Encoding6 { - html_tags?: string; - body: string; - body_hash: string; - html_title?: string; -} - -export interface Favicon { - size: number; - name: string; - md5_hash: string; -} - -export interface Jarm { - _encoding: Encoding7; - fingerprint: string; - cipher_and_version_fingerprint: string; - tls_extensions_sha256: string; - observed_at: string; -} - -export interface Encoding7 { - fingerprint: string; - cipher_and_version_fingerprint: string; - tls_extensions_sha256: string; -} - -export interface Tls { - version_selected: string; - cipher_selected: string; - certificates: Certificates; - _encoding: Encoding10; - ja3s: string; -} - -export interface Certificates { - _encoding: Encoding8; - leaf_fp_sha_256: string; - leaf_data: LeafData; -} - -export interface Encoding8 { - leaf_fp_sha_256: string; -} - -export interface LeafData { - names: string[]; - subject_dn: string; - issuer_dn: string; - pubkey_bit_size: number; - pubkey_algorithm: string; - tbs_fingerprint: string; - fingerprint: string; - issuer: Issuer; - subject: Subject; - public_key: PublicKey; - signature: Signature; -} - -export interface Issuer { - common_name: string[]; - organization: string[]; - country: string[]; -} - -export interface Subject { - common_name: string[]; -} - -export interface PublicKey { - key_algorithm: string; - rsa: Rsa; - fingerprint: string; -} - -export interface Rsa { - _encoding: Encoding9; - modulus: string; - exponent: string; - length: number; -} - -export interface Encoding9 { - modulus: string; - exponent: string; -} - -export interface Signature { - signature_algorithm: string; - self_signed: boolean; -} - -export interface Encoding10 { - ja3s: string; -} - -export interface Location { - continent: string; - country: string; - country_code: string; - city: string; - timezone: string; - province: string; - coordinates: Coordinates; -} - -export interface Coordinates { - latitude: number; - longitude: number; -} - -export interface AutonomousSystem { - asn: number; - description: string; - bgp_prefix: string; - name: string; - country_code: string; -} - -export interface Dns { - names: string[]; - records: Records; -} - -export interface Records { - "junlongchat.cloud": JunlongchatCloud; -} - -export interface JunlongchatCloud { - record_type: string; - resolved_at: string; -} diff --git a/anify-backend/src/helper/proxies/proxies.json b/anify-backend/src/helper/proxies/proxies.json deleted file mode 100644 index 01e485a..0000000 --- a/anify-backend/src/helper/proxies/proxies.json +++ /dev/null @@ -1,29946 +0,0 @@ -[ - { - "ip": "3.39.225.40", - "port": 80 - }, - { - "ip": "3.39.225.40", - "port": 5357 - }, - { - "ip": "3.39.225.40", - "port": 5985 - }, - { - "ip": "3.39.225.40", - "port": 8080 - }, - { - "ip": "3.39.225.40", - "port": 8085 - }, - { - "ip": "3.39.225.40", - "port": 47001 - }, - { - "ip": "13.124.46.36", - "port": 80 - }, - { - "ip": "13.124.46.36", - "port": 8080 - }, - { - "ip": "13.124.30.35", - "port": 8080 - }, - { - "ip": "199.192.22.207", - "port": 80 - }, - { - "ip": "199.192.22.207", - "port": 443 - }, - { - "ip": "199.192.22.207", - "port": 1234 - }, - { - "ip": "199.192.22.207", - "port": 2087 - }, - { - "ip": "199.192.22.207", - "port": 2096 - }, - { - "ip": "199.192.22.207", - "port": 3006 - }, - { - "ip": "199.192.22.207", - "port": 8081 - }, - { - "ip": "199.192.22.207", - "port": 8443 - }, - { - "ip": "35.209.252.248", - "port": 8088 - }, - { - "ip": "35.209.252.248", - "port": 9100 - }, - { - "ip": "35.209.252.248", - "port": 9209 - }, - { - "ip": "54.88.85.128", - "port": 80 - }, - { - "ip": "118.42.203.187", - "port": 84 - }, - { - "ip": "118.42.203.187", - "port": 8080 - }, - { - "ip": "118.42.203.187", - "port": 9935 - }, - { - "ip": "3.125.57.252", - "port": 3000 - }, - { - "ip": "3.125.57.252", - "port": 3001 - }, - { - "ip": "3.125.57.252", - "port": 3002 - }, - { - "ip": "3.125.57.252", - "port": 3008 - }, - { - "ip": "3.125.57.252", - "port": 5080 - }, - { - "ip": "3.125.57.252", - "port": 8080 - }, - { - "ip": "34.78.67.250", - "port": 80 - }, - { - "ip": "34.78.67.250", - "port": 443 - }, - { - "ip": "34.78.67.250", - "port": 8080 - }, - { - "ip": "45.78.67.83", - "port": 80 - }, - { - "ip": "45.78.67.83", - "port": 443 - }, - { - "ip": "45.78.67.83", - "port": 9299 - }, - { - "ip": "45.78.67.83", - "port": 9901 - }, - { - "ip": "46.51.220.41", - "port": 80 - }, - { - "ip": "46.229.168.236", - "port": 80 - }, - { - "ip": "46.229.168.236", - "port": 81 - }, - { - "ip": "46.229.168.236", - "port": 443 - }, - { - "ip": "46.229.168.236", - "port": 3010 - }, - { - "ip": "47.94.13.234", - "port": 3223 - }, - { - "ip": "47.94.13.234", - "port": 8100 - }, - { - "ip": "47.94.13.234", - "port": 8101 - }, - { - "ip": "47.94.13.234", - "port": 8110 - }, - { - "ip": "47.94.13.234", - "port": 8773 - }, - { - "ip": "47.94.13.234", - "port": 19999 - }, - { - "ip": "103.135.49.202", - "port": 80 - }, - { - "ip": "103.135.49.202", - "port": 1500 - }, - { - "ip": "103.135.49.202", - "port": 5000 - }, - { - "ip": "222.237.27.166", - "port": 80 - }, - { - "ip": "222.237.27.166", - "port": 84 - }, - { - "ip": "222.237.27.166", - "port": 8080 - }, - { - "ip": "222.237.27.166", - "port": 9935 - }, - { - "ip": "15.228.85.121", - "port": 4000 - }, - { - "ip": "15.228.85.121", - "port": 6000 - }, - { - "ip": "15.228.85.121", - "port": 6050 - }, - { - "ip": "15.228.85.121", - "port": 7000 - }, - { - "ip": "15.228.85.121", - "port": 7050 - }, - { - "ip": "15.228.85.121", - "port": 7500 - }, - { - "ip": "15.228.85.121", - "port": 7777 - }, - { - "ip": "15.228.85.121", - "port": 8000 - }, - { - "ip": "15.228.85.121", - "port": 8001 - }, - { - "ip": "15.228.85.121", - "port": 8050 - }, - { - "ip": "15.228.85.121", - "port": 8700 - }, - { - "ip": "15.228.85.121", - "port": 8893 - }, - { - "ip": "15.228.85.121", - "port": 9001 - }, - { - "ip": "15.228.85.121", - "port": 9005 - }, - { - "ip": "15.228.85.121", - "port": 9006 - }, - { - "ip": "15.228.85.121", - "port": 9008 - }, - { - "ip": "15.228.85.121", - "port": 9010 - }, - { - "ip": "15.228.85.121", - "port": 9011 - }, - { - "ip": "15.228.85.121", - "port": 9012 - }, - { - "ip": "15.228.85.121", - "port": 9999 - }, - { - "ip": "15.228.85.121", - "port": 30000 - }, - { - "ip": "204.48.27.255", - "port": 80 - }, - { - "ip": "204.48.27.255", - "port": 443 - }, - { - "ip": "204.48.27.255", - "port": 8080 - }, - { - "ip": "204.48.27.255", - "port": 8081 - }, - { - "ip": "211.51.150.200", - "port": 80 - }, - { - "ip": "211.51.150.200", - "port": 84 - }, - { - "ip": "211.51.150.200", - "port": 443 - }, - { - "ip": "211.51.150.200", - "port": 8080 - }, - { - "ip": "35.200.179.57", - "port": 80 - }, - { - "ip": "35.200.179.57", - "port": 84 - }, - { - "ip": "35.200.179.57", - "port": 85 - }, - { - "ip": "35.200.179.57", - "port": 443 - }, - { - "ip": "35.200.179.57", - "port": 3001 - }, - { - "ip": "35.200.179.57", - "port": 3002 - }, - { - "ip": "35.200.179.57", - "port": 8004 - }, - { - "ip": "35.200.179.57", - "port": 8013 - }, - { - "ip": "35.200.179.57", - "port": 8017 - }, - { - "ip": "35.200.179.57", - "port": 8019 - }, - { - "ip": "35.200.179.57", - "port": 8022 - }, - { - "ip": "35.200.179.57", - "port": 8023 - }, - { - "ip": "35.200.179.57", - "port": 8024 - }, - { - "ip": "35.200.179.57", - "port": 8025 - }, - { - "ip": "35.200.179.57", - "port": 8028 - }, - { - "ip": "35.200.179.57", - "port": 8029 - }, - { - "ip": "35.200.179.57", - "port": 8030 - }, - { - "ip": "35.200.179.57", - "port": 8032 - }, - { - "ip": "35.200.179.57", - "port": 8034 - }, - { - "ip": "35.200.179.57", - "port": 8036 - }, - { - "ip": "35.200.179.57", - "port": 8037 - }, - { - "ip": "35.200.179.57", - "port": 8038 - }, - { - "ip": "35.200.179.57", - "port": 8040 - }, - { - "ip": "35.200.179.57", - "port": 8042 - }, - { - "ip": "35.200.179.57", - "port": 8045 - }, - { - "ip": "35.200.179.57", - "port": 8050 - }, - { - "ip": "35.200.179.57", - "port": 8052 - }, - { - "ip": "35.200.179.57", - "port": 8054 - }, - { - "ip": "35.200.179.57", - "port": 8060 - }, - { - "ip": "35.200.179.57", - "port": 8062 - }, - { - "ip": "35.200.179.57", - "port": 8063 - }, - { - "ip": "35.200.179.57", - "port": 8080 - }, - { - "ip": "35.200.179.57", - "port": 8099 - }, - { - "ip": "35.200.179.57", - "port": 8181 - }, - { - "ip": "84.16.241.179", - "port": 80 - }, - { - "ip": "84.16.241.179", - "port": 443 - }, - { - "ip": "84.16.241.179", - "port": 2058 - }, - { - "ip": "84.16.241.179", - "port": 3000 - }, - { - "ip": "84.16.241.179", - "port": 8000 - }, - { - "ip": "84.16.241.179", - "port": 8182 - }, - { - "ip": "108.136.162.241", - "port": 80 - }, - { - "ip": "108.136.162.241", - "port": 443 - }, - { - "ip": "108.136.162.241", - "port": 1337 - }, - { - "ip": "108.136.162.241", - "port": 3000 - }, - { - "ip": "108.136.162.241", - "port": 4000 - }, - { - "ip": "108.136.162.241", - "port": 8080 - }, - { - "ip": "159.69.124.78", - "port": 80 - }, - { - "ip": "159.69.124.78", - "port": 443 - }, - { - "ip": "159.69.124.78", - "port": 4001 - }, - { - "ip": "159.69.124.78", - "port": 4010 - }, - { - "ip": "159.69.124.78", - "port": 8900 - }, - { - "ip": "159.69.124.78", - "port": 8910 - }, - { - "ip": "159.69.124.78", - "port": 9000 - }, - { - "ip": "159.69.124.78", - "port": 9999 - }, - { - "ip": "159.69.124.78", - "port": 11000 - }, - { - "ip": "159.69.124.78", - "port": 11300 - }, - { - "ip": "159.69.124.78", - "port": 20000 - }, - { - "ip": "199.170.132.83", - "port": 80 - }, - { - "ip": "35.155.192.226", - "port": 80 - }, - { - "ip": "35.155.192.226", - "port": 8080 - }, - { - "ip": "81.29.108.47", - "port": 3000 - }, - { - "ip": "81.29.108.47", - "port": 3001 - }, - { - "ip": "81.29.108.47", - "port": 3002 - }, - { - "ip": "141.94.150.68", - "port": 80 - }, - { - "ip": "141.94.150.68", - "port": 443 - }, - { - "ip": "141.94.150.68", - "port": 3102 - }, - { - "ip": "141.94.150.68", - "port": 8080 - }, - { - "ip": "141.94.150.68", - "port": 8443 - }, - { - "ip": "141.94.150.68", - "port": 10000 - }, - { - "ip": "141.94.150.68", - "port": 20000 - }, - { - "ip": "44.212.167.160", - "port": 80 - }, - { - "ip": "85.90.245.31", - "port": 80 - }, - { - "ip": "85.90.245.31", - "port": 443 - }, - { - "ip": "85.90.245.31", - "port": 3001 - }, - { - "ip": "85.90.245.31", - "port": 8070 - }, - { - "ip": "85.90.245.31", - "port": 8083 - }, - { - "ip": "85.90.245.31", - "port": 8089 - }, - { - "ip": "85.90.245.31", - "port": 8090 - }, - { - "ip": "85.90.245.31", - "port": 8091 - }, - { - "ip": "85.90.245.31", - "port": 8170 - }, - { - "ip": "85.90.245.31", - "port": 8171 - }, - { - "ip": "85.90.245.31", - "port": 8172 - }, - { - "ip": "85.90.245.31", - "port": 8181 - }, - { - "ip": "85.90.245.31", - "port": 8380 - }, - { - "ip": "85.90.245.31", - "port": 49153 - }, - { - "ip": "125.134.87.145", - "port": 80 - }, - { - "ip": "125.134.87.145", - "port": 84 - }, - { - "ip": "125.134.87.145", - "port": 8080 - }, - { - "ip": "125.134.87.145", - "port": 9935 - }, - { - "ip": "207.180.245.70", - "port": 80 - }, - { - "ip": "207.180.245.70", - "port": 443 - }, - { - "ip": "207.180.245.70", - "port": 3002 - }, - { - "ip": "207.180.245.70", - "port": 3020 - }, - { - "ip": "207.180.245.70", - "port": 3021 - }, - { - "ip": "207.180.245.70", - "port": 4001 - }, - { - "ip": "207.180.245.70", - "port": 4002 - }, - { - "ip": "207.180.245.70", - "port": 8080 - }, - { - "ip": "1.117.1.77", - "port": 8181 - }, - { - "ip": "109.72.149.152", - "port": 80 - }, - { - "ip": "109.72.149.152", - "port": 443 - }, - { - "ip": "109.72.149.152", - "port": 5050 - }, - { - "ip": "109.72.149.152", - "port": 8111 - }, - { - "ip": "109.72.149.152", - "port": 30000 - }, - { - "ip": "218.48.51.200", - "port": 84 - }, - { - "ip": "218.48.51.200", - "port": 8080 - }, - { - "ip": "218.48.51.200", - "port": 9935 - }, - { - "ip": "35.175.120.115", - "port": 7088 - }, - { - "ip": "35.175.120.115", - "port": 8080 - }, - { - "ip": "35.175.120.115", - "port": 8088 - }, - { - "ip": "35.175.120.115", - "port": 8188 - }, - { - "ip": "175.214.254.139", - "port": 80 - }, - { - "ip": "175.214.254.139", - "port": 84 - }, - { - "ip": "175.214.254.139", - "port": 443 - }, - { - "ip": "175.214.254.139", - "port": 8080 - }, - { - "ip": "175.214.254.139", - "port": 9935 - }, - { - "ip": "188.68.39.67", - "port": 80 - }, - { - "ip": "188.68.39.67", - "port": 443 - }, - { - "ip": "188.68.39.67", - "port": 3030 - }, - { - "ip": "188.68.39.67", - "port": 20000 - }, - { - "ip": "188.68.39.67", - "port": 20002 - }, - { - "ip": "189.111.202.183", - "port": 3210 - }, - { - "ip": "189.111.202.183", - "port": 5050 - }, - { - "ip": "189.111.202.183", - "port": 5051 - }, - { - "ip": "189.111.202.183", - "port": 8001 - }, - { - "ip": "203.254.224.41", - "port": 80 - }, - { - "ip": "44.207.110.123", - "port": 80 - }, - { - "ip": "44.207.110.123", - "port": 3000 - }, - { - "ip": "44.207.110.123", - "port": 8080 - }, - { - "ip": "125.132.26.201", - "port": 80 - }, - { - "ip": "125.132.26.201", - "port": 84 - }, - { - "ip": "125.132.26.201", - "port": 8080 - }, - { - "ip": "125.132.26.201", - "port": 9935 - }, - { - "ip": "8.33.239.227", - "port": 80 - }, - { - "ip": "8.33.239.227", - "port": 443 - }, - { - "ip": "8.33.239.227", - "port": 8080 - }, - { - "ip": "77.91.69.186", - "port": 80 - }, - { - "ip": "180.150.79.23", - "port": 5000 - }, - { - "ip": "180.150.79.23", - "port": 8080 - }, - { - "ip": "180.150.79.23", - "port": 32400 - }, - { - "ip": "35.197.68.53", - "port": 5473 - }, - { - "ip": "35.197.68.53", - "port": 5552 - }, - { - "ip": "35.197.68.53", - "port": 5563 - }, - { - "ip": "35.197.68.53", - "port": 5594 - }, - { - "ip": "35.197.68.53", - "port": 5606 - }, - { - "ip": "35.197.68.53", - "port": 5642 - }, - { - "ip": "35.197.68.53", - "port": 5986 - }, - { - "ip": "35.197.68.53", - "port": 5998 - }, - { - "ip": "35.197.68.53", - "port": 6006 - }, - { - "ip": "35.197.68.53", - "port": 6009 - }, - { - "ip": "35.197.68.53", - "port": 6093 - }, - { - "ip": "35.197.68.53", - "port": 6113 - }, - { - "ip": "35.197.68.53", - "port": 6260 - }, - { - "ip": "35.197.68.53", - "port": 6320 - }, - { - "ip": "35.197.68.53", - "port": 6467 - }, - { - "ip": "35.197.68.53", - "port": 6588 - }, - { - "ip": "35.197.68.53", - "port": 6686 - }, - { - "ip": "35.197.68.53", - "port": 6692 - }, - { - "ip": "35.197.68.53", - "port": 6749 - }, - { - "ip": "35.197.68.53", - "port": 6789 - }, - { - "ip": "35.197.68.53", - "port": 6904 - }, - { - "ip": "35.197.68.53", - "port": 6945 - }, - { - "ip": "35.197.68.53", - "port": 6947 - }, - { - "ip": "35.197.68.53", - "port": 6963 - }, - { - "ip": "35.197.68.53", - "port": 6999 - }, - { - "ip": "35.197.68.53", - "port": 7015 - }, - { - "ip": "35.197.68.53", - "port": 7071 - }, - { - "ip": "35.197.68.53", - "port": 7141 - }, - { - "ip": "35.197.68.53", - "port": 7149 - }, - { - "ip": "35.197.68.53", - "port": 7182 - }, - { - "ip": "35.197.68.53", - "port": 7206 - }, - { - "ip": "35.197.68.53", - "port": 7231 - }, - { - "ip": "35.197.68.53", - "port": 7366 - }, - { - "ip": "35.197.68.53", - "port": 7373 - }, - { - "ip": "35.197.68.53", - "port": 7385 - }, - { - "ip": "35.197.68.53", - "port": 7487 - }, - { - "ip": "35.197.68.53", - "port": 7500 - }, - { - "ip": "35.197.68.53", - "port": 7535 - }, - { - "ip": "35.197.68.53", - "port": 7571 - }, - { - "ip": "35.197.68.53", - "port": 7604 - }, - { - "ip": "35.197.68.53", - "port": 7777 - }, - { - "ip": "35.197.68.53", - "port": 7821 - }, - { - "ip": "35.197.68.53", - "port": 7980 - }, - { - "ip": "35.197.68.53", - "port": 8000 - }, - { - "ip": "35.197.68.53", - "port": 8012 - }, - { - "ip": "35.197.68.53", - "port": 8016 - }, - { - "ip": "35.197.68.53", - "port": 8024 - }, - { - "ip": "35.197.68.53", - "port": 8030 - }, - { - "ip": "35.197.68.53", - "port": 8042 - }, - { - "ip": "35.197.68.53", - "port": 8046 - }, - { - "ip": "35.197.68.53", - "port": 8047 - }, - { - "ip": "35.197.68.53", - "port": 8057 - }, - { - "ip": "35.197.68.53", - "port": 8067 - }, - { - "ip": "121.156.215.13", - "port": 80 - }, - { - "ip": "121.156.215.13", - "port": 81 - }, - { - "ip": "121.156.215.13", - "port": 84 - }, - { - "ip": "121.156.215.13", - "port": 443 - }, - { - "ip": "121.156.215.13", - "port": 8080 - }, - { - "ip": "121.156.215.13", - "port": 9935 - }, - { - "ip": "187.75.185.85", - "port": 1551 - }, - { - "ip": "187.75.185.85", - "port": 1554 - }, - { - "ip": "187.75.185.85", - "port": 3358 - }, - { - "ip": "187.75.185.85", - "port": 6002 - }, - { - "ip": "187.75.185.85", - "port": 6003 - }, - { - "ip": "187.75.185.85", - "port": 6004 - }, - { - "ip": "187.75.185.85", - "port": 6005 - }, - { - "ip": "187.75.185.85", - "port": 8068 - }, - { - "ip": "187.75.185.85", - "port": 8081 - }, - { - "ip": "187.75.185.85", - "port": 8083 - }, - { - "ip": "187.75.185.85", - "port": 8084 - }, - { - "ip": "187.75.185.85", - "port": 8085 - }, - { - "ip": "187.75.185.85", - "port": 8161 - }, - { - "ip": "187.75.185.85", - "port": 8162 - }, - { - "ip": "187.75.185.85", - "port": 8163 - }, - { - "ip": "187.75.185.85", - "port": 8164 - }, - { - "ip": "187.75.185.85", - "port": 8165 - }, - { - "ip": "187.75.185.85", - "port": 8240 - }, - { - "ip": "187.75.185.85", - "port": 8241 - }, - { - "ip": "187.75.185.85", - "port": 8242 - }, - { - "ip": "187.75.185.85", - "port": 8243 - }, - { - "ip": "187.75.185.85", - "port": 8262 - }, - { - "ip": "187.75.185.85", - "port": 8480 - }, - { - "ip": "187.75.185.85", - "port": 8481 - }, - { - "ip": "187.75.185.85", - "port": 8570 - }, - { - "ip": "187.75.185.85", - "port": 8571 - }, - { - "ip": "187.75.185.85", - "port": 8573 - }, - { - "ip": "187.75.185.85", - "port": 8574 - }, - { - "ip": "187.75.185.85", - "port": 8575 - }, - { - "ip": "187.75.185.85", - "port": 8576 - }, - { - "ip": "187.75.185.85", - "port": 8577 - }, - { - "ip": "187.75.185.85", - "port": 8578 - }, - { - "ip": "187.75.185.85", - "port": 8579 - }, - { - "ip": "187.75.185.85", - "port": 8861 - }, - { - "ip": "187.75.185.85", - "port": 8862 - }, - { - "ip": "187.75.185.85", - "port": 8863 - }, - { - "ip": "187.75.185.85", - "port": 8864 - }, - { - "ip": "187.75.185.85", - "port": 8865 - }, - { - "ip": "187.75.185.85", - "port": 9999 - }, - { - "ip": "187.75.185.85", - "port": 55030 - }, - { - "ip": "187.75.185.85", - "port": 55085 - }, - { - "ip": "211.23.29.201", - "port": 80 - }, - { - "ip": "211.23.29.201", - "port": 443 - }, - { - "ip": "211.23.29.201", - "port": 5050 - }, - { - "ip": "211.23.29.201", - "port": 5600 - }, - { - "ip": "211.23.29.201", - "port": 7001 - }, - { - "ip": "211.23.29.201", - "port": 7002 - }, - { - "ip": "211.23.29.201", - "port": 7003 - }, - { - "ip": "211.23.29.201", - "port": 8080 - }, - { - "ip": "211.23.29.201", - "port": 8083 - }, - { - "ip": "211.23.29.201", - "port": 15672 - }, - { - "ip": "211.23.29.201", - "port": 18083 - }, - { - "ip": "3.1.190.110", - "port": 80 - }, - { - "ip": "3.1.190.110", - "port": 443 - }, - { - "ip": "3.1.190.110", - "port": 8080 - }, - { - "ip": "87.107.147.237", - "port": 80 - }, - { - "ip": "87.107.147.237", - "port": 443 - }, - { - "ip": "87.107.147.237", - "port": 1337 - }, - { - "ip": "87.107.147.237", - "port": 3005 - }, - { - "ip": "87.107.147.237", - "port": 3199 - }, - { - "ip": "87.107.147.237", - "port": 4080 - }, - { - "ip": "87.107.147.237", - "port": 4200 - }, - { - "ip": "87.107.147.237", - "port": 4300 - }, - { - "ip": "87.107.147.237", - "port": 5601 - }, - { - "ip": "87.107.147.237", - "port": 8089 - }, - { - "ip": "87.107.147.237", - "port": 9001 - }, - { - "ip": "87.107.147.237", - "port": 9002 - }, - { - "ip": "87.107.147.237", - "port": 9600 - }, - { - "ip": "87.107.147.237", - "port": 17001 - }, - { - "ip": "87.107.147.237", - "port": 18000 - }, - { - "ip": "87.107.147.237", - "port": 20000 - }, - { - "ip": "106.255.224.174", - "port": 80 - }, - { - "ip": "106.255.224.174", - "port": 5985 - }, - { - "ip": "106.255.224.174", - "port": 8080 - }, - { - "ip": "106.255.224.174", - "port": 47001 - }, - { - "ip": "190.252.224.109", - "port": 80 - }, - { - "ip": "190.252.224.109", - "port": 91 - }, - { - "ip": "190.252.224.109", - "port": 8001 - }, - { - "ip": "190.252.224.109", - "port": 8002 - }, - { - "ip": "190.252.224.109", - "port": 8090 - }, - { - "ip": "190.252.224.109", - "port": 8383 - }, - { - "ip": "190.252.224.109", - "port": 9191 - }, - { - "ip": "190.252.224.109", - "port": 12000 - }, - { - "ip": "35.220.209.40", - "port": 80 - }, - { - "ip": "35.220.209.40", - "port": 443 - }, - { - "ip": "35.220.209.40", - "port": 8080 - }, - { - "ip": "59.151.196.252", - "port": 80 - }, - { - "ip": "59.151.196.252", - "port": 84 - }, - { - "ip": "59.151.196.252", - "port": 8080 - }, - { - "ip": "59.151.196.252", - "port": 9935 - }, - { - "ip": "110.4.41.173", - "port": 80 - }, - { - "ip": "110.4.41.173", - "port": 443 - }, - { - "ip": "110.4.41.173", - "port": 1781 - }, - { - "ip": "110.4.41.173", - "port": 3002 - }, - { - "ip": "110.4.41.173", - "port": 3091 - }, - { - "ip": "110.4.41.173", - "port": 3092 - }, - { - "ip": "110.4.41.173", - "port": 3093 - }, - { - "ip": "110.4.41.173", - "port": 3097 - }, - { - "ip": "110.4.41.173", - "port": 3099 - }, - { - "ip": "110.4.41.173", - "port": 3199 - }, - { - "ip": "110.4.41.173", - "port": 3222 - }, - { - "ip": "110.4.41.173", - "port": 3251 - }, - { - "ip": "110.4.41.173", - "port": 3254 - }, - { - "ip": "110.4.41.173", - "port": 3263 - }, - { - "ip": "110.4.41.173", - "port": 3333 - }, - { - "ip": "110.4.41.173", - "port": 3400 - }, - { - "ip": "110.4.41.173", - "port": 3456 - }, - { - "ip": "110.4.41.173", - "port": 3500 - }, - { - "ip": "110.4.41.173", - "port": 5000 - }, - { - "ip": "110.4.41.173", - "port": 6822 - }, - { - "ip": "110.4.41.173", - "port": 6840 - }, - { - "ip": "110.4.41.173", - "port": 6841 - }, - { - "ip": "110.4.41.173", - "port": 6843 - }, - { - "ip": "110.4.41.173", - "port": 6847 - }, - { - "ip": "110.4.41.173", - "port": 6848 - }, - { - "ip": "110.4.41.173", - "port": 6849 - }, - { - "ip": "110.4.41.173", - "port": 6860 - }, - { - "ip": "110.4.41.173", - "port": 7000 - }, - { - "ip": "110.4.41.173", - "port": 8443 - }, - { - "ip": "110.4.41.173", - "port": 8529 - }, - { - "ip": "110.4.41.173", - "port": 8880 - }, - { - "ip": "20.212.233.191", - "port": 8080 - }, - { - "ip": "118.47.169.34", - "port": 80 - }, - { - "ip": "118.47.169.34", - "port": 84 - }, - { - "ip": "118.47.169.34", - "port": 6500 - }, - { - "ip": "118.47.169.34", - "port": 8080 - }, - { - "ip": "118.47.169.34", - "port": 8090 - }, - { - "ip": "139.59.105.218", - "port": 80 - }, - { - "ip": "139.59.105.218", - "port": 10250 - }, - { - "ip": "139.59.105.218", - "port": 10256 - }, - { - "ip": "139.59.105.218", - "port": 30002 - }, - { - "ip": "139.59.105.218", - "port": 30003 - }, - { - "ip": "139.59.105.218", - "port": 30005 - }, - { - "ip": "139.59.105.218", - "port": 30006 - }, - { - "ip": "139.59.105.218", - "port": 30008 - }, - { - "ip": "139.59.105.218", - "port": 30009 - }, - { - "ip": "139.59.105.218", - "port": 30010 - }, - { - "ip": "139.59.105.218", - "port": 30011 - }, - { - "ip": "139.59.105.218", - "port": 30013 - }, - { - "ip": "139.59.105.218", - "port": 30015 - }, - { - "ip": "139.59.105.218", - "port": 30017 - }, - { - "ip": "139.59.105.218", - "port": 30018 - }, - { - "ip": "139.59.105.218", - "port": 30021 - }, - { - "ip": "139.59.105.218", - "port": 30023 - }, - { - "ip": "139.59.105.218", - "port": 30025 - }, - { - "ip": "139.59.105.218", - "port": 30027 - }, - { - "ip": "139.59.105.218", - "port": 30028 - }, - { - "ip": "139.59.105.218", - "port": 30029 - }, - { - "ip": "139.59.105.218", - "port": 30030 - }, - { - "ip": "139.59.105.218", - "port": 30031 - }, - { - "ip": "139.59.105.218", - "port": 30035 - }, - { - "ip": "139.59.105.218", - "port": 30038 - }, - { - "ip": "139.59.105.218", - "port": 30039 - }, - { - "ip": "139.59.105.218", - "port": 30043 - }, - { - "ip": "139.59.105.218", - "port": 30046 - }, - { - "ip": "139.59.105.218", - "port": 30048 - }, - { - "ip": "139.59.105.218", - "port": 30050 - }, - { - "ip": "139.59.105.218", - "port": 31006 - }, - { - "ip": "139.59.105.218", - "port": 31007 - }, - { - "ip": "139.59.105.218", - "port": 31010 - }, - { - "ip": "139.59.105.218", - "port": 31012 - }, - { - "ip": "139.59.105.218", - "port": 31015 - }, - { - "ip": "139.59.105.218", - "port": 31024 - }, - { - "ip": "139.59.105.218", - "port": 31025 - }, - { - "ip": "217.70.189.221", - "port": 80 - }, - { - "ip": "217.70.189.221", - "port": 443 - }, - { - "ip": "217.70.189.221", - "port": 8066 - }, - { - "ip": "217.70.189.221", - "port": 8080 - }, - { - "ip": "220.120.200.3", - "port": 80 - }, - { - "ip": "220.120.200.3", - "port": 81 - }, - { - "ip": "220.120.200.3", - "port": 84 - }, - { - "ip": "220.120.200.3", - "port": 443 - }, - { - "ip": "220.120.200.3", - "port": 8080 - }, - { - "ip": "220.120.200.3", - "port": 9935 - }, - { - "ip": "58.75.220.74", - "port": 84 - }, - { - "ip": "58.75.220.74", - "port": 8080 - }, - { - "ip": "59.16.141.47", - "port": 80 - }, - { - "ip": "59.16.141.47", - "port": 84 - }, - { - "ip": "59.16.141.47", - "port": 6500 - }, - { - "ip": "59.16.141.47", - "port": 8080 - }, - { - "ip": "59.16.141.47", - "port": 8090 - }, - { - "ip": "103.164.203.14", - "port": 80 - }, - { - "ip": "103.164.203.14", - "port": 443 - }, - { - "ip": "103.164.203.14", - "port": 8935 - }, - { - "ip": "139.17.228.154", - "port": 8080 - }, - { - "ip": "139.17.228.154", - "port": 8081 - }, - { - "ip": "139.17.228.154", - "port": 8082 - }, - { - "ip": "159.69.62.59", - "port": 80 - }, - { - "ip": "159.69.62.59", - "port": 2053 - }, - { - "ip": "47.106.95.141", - "port": 80 - }, - { - "ip": "47.106.95.141", - "port": 8866 - }, - { - "ip": "51.15.134.127", - "port": 80 - }, - { - "ip": "51.15.134.127", - "port": 443 - }, - { - "ip": "51.15.134.127", - "port": 3001 - }, - { - "ip": "51.15.134.127", - "port": 3002 - }, - { - "ip": "51.15.134.127", - "port": 5000 - }, - { - "ip": "51.15.134.127", - "port": 8081 - }, - { - "ip": "51.178.15.186", - "port": 80 - }, - { - "ip": "51.178.15.186", - "port": 443 - }, - { - "ip": "51.178.15.186", - "port": 5443 - }, - { - "ip": "51.178.15.186", - "port": 10000 - }, - { - "ip": "54.171.109.131", - "port": 80 - }, - { - "ip": "54.171.109.131", - "port": 443 - }, - { - "ip": "54.171.109.131", - "port": 8081 - }, - { - "ip": "13.251.114.167", - "port": 80 - }, - { - "ip": "54.234.139.208", - "port": 4000 - }, - { - "ip": "115.92.74.234", - "port": 8080 - }, - { - "ip": "115.92.74.234", - "port": 9935 - }, - { - "ip": "140.238.154.147", - "port": 8088 - }, - { - "ip": "140.238.154.147", - "port": 8089 - }, - { - "ip": "211.117.69.242", - "port": 80 - }, - { - "ip": "211.117.69.242", - "port": 84 - }, - { - "ip": "211.117.69.242", - "port": 443 - }, - { - "ip": "211.117.69.242", - "port": 8080 - }, - { - "ip": "14.225.192.147", - "port": 80 - }, - { - "ip": "14.225.192.147", - "port": 443 - }, - { - "ip": "14.225.192.147", - "port": 1606 - }, - { - "ip": "14.225.192.147", - "port": 3008 - }, - { - "ip": "14.225.192.147", - "port": 3010 - }, - { - "ip": "14.225.192.147", - "port": 3100 - }, - { - "ip": "14.225.192.147", - "port": 3334 - }, - { - "ip": "14.225.192.147", - "port": 8080 - }, - { - "ip": "34.105.6.235", - "port": 5468 - }, - { - "ip": "34.105.6.235", - "port": 5569 - }, - { - "ip": "34.105.6.235", - "port": 5592 - }, - { - "ip": "34.105.6.235", - "port": 5696 - }, - { - "ip": "34.105.6.235", - "port": 5902 - }, - { - "ip": "34.105.6.235", - "port": 5910 - }, - { - "ip": "34.105.6.235", - "port": 6002 - }, - { - "ip": "34.105.6.235", - "port": 6136 - }, - { - "ip": "34.105.6.235", - "port": 6164 - }, - { - "ip": "34.105.6.235", - "port": 6206 - }, - { - "ip": "34.105.6.235", - "port": 6253 - }, - { - "ip": "34.105.6.235", - "port": 6316 - }, - { - "ip": "34.105.6.235", - "port": 6363 - }, - { - "ip": "34.105.6.235", - "port": 6433 - }, - { - "ip": "34.105.6.235", - "port": 6452 - }, - { - "ip": "34.105.6.235", - "port": 6467 - }, - { - "ip": "34.105.6.235", - "port": 6482 - }, - { - "ip": "34.105.6.235", - "port": 6488 - }, - { - "ip": "34.105.6.235", - "port": 6505 - }, - { - "ip": "34.105.6.235", - "port": 6507 - }, - { - "ip": "34.105.6.235", - "port": 6565 - }, - { - "ip": "34.105.6.235", - "port": 6576 - }, - { - "ip": "34.105.6.235", - "port": 6618 - }, - { - "ip": "34.105.6.235", - "port": 6661 - }, - { - "ip": "34.105.6.235", - "port": 6666 - }, - { - "ip": "34.105.6.235", - "port": 6700 - }, - { - "ip": "34.105.6.235", - "port": 7016 - }, - { - "ip": "34.105.6.235", - "port": 7023 - }, - { - "ip": "34.105.6.235", - "port": 7080 - }, - { - "ip": "34.105.6.235", - "port": 7081 - }, - { - "ip": "34.105.6.235", - "port": 7232 - }, - { - "ip": "34.105.6.235", - "port": 7264 - }, - { - "ip": "34.105.6.235", - "port": 7352 - }, - { - "ip": "34.105.6.235", - "port": 7533 - }, - { - "ip": "34.105.6.235", - "port": 7613 - }, - { - "ip": "34.105.6.235", - "port": 7718 - }, - { - "ip": "34.105.6.235", - "port": 7754 - }, - { - "ip": "34.105.6.235", - "port": 7776 - }, - { - "ip": "34.105.6.235", - "port": 7854 - }, - { - "ip": "34.105.6.235", - "port": 7878 - }, - { - "ip": "34.105.6.235", - "port": 7974 - }, - { - "ip": "34.105.6.235", - "port": 7988 - }, - { - "ip": "34.105.6.235", - "port": 7995 - }, - { - "ip": "34.105.6.235", - "port": 7999 - }, - { - "ip": "34.105.6.235", - "port": 8015 - }, - { - "ip": "34.105.6.235", - "port": 8021 - }, - { - "ip": "34.105.6.235", - "port": 8027 - }, - { - "ip": "34.105.6.235", - "port": 8052 - }, - { - "ip": "34.105.6.235", - "port": 8067 - }, - { - "ip": "119.195.100.108", - "port": 80 - }, - { - "ip": "119.195.100.108", - "port": 84 - }, - { - "ip": "119.195.100.108", - "port": 8080 - }, - { - "ip": "119.195.100.108", - "port": 9935 - }, - { - "ip": "52.37.234.32", - "port": 80 - }, - { - "ip": "92.51.167.111", - "port": 80 - }, - { - "ip": "92.51.167.111", - "port": 443 - }, - { - "ip": "92.51.167.111", - "port": 8402 - }, - { - "ip": "92.51.167.111", - "port": 8443 - }, - { - "ip": "92.51.167.111", - "port": 8880 - }, - { - "ip": "138.68.115.164", - "port": 80 - }, - { - "ip": "138.68.115.164", - "port": 443 - }, - { - "ip": "138.68.115.164", - "port": 3000 - }, - { - "ip": "138.68.115.164", - "port": 3100 - }, - { - "ip": "138.68.115.164", - "port": 4000 - }, - { - "ip": "138.68.115.164", - "port": 8000 - }, - { - "ip": "138.68.115.164", - "port": 8080 - }, - { - "ip": "5.252.231.50", - "port": 80 - }, - { - "ip": "5.252.231.50", - "port": 443 - }, - { - "ip": "5.252.231.50", - "port": 8080 - }, - { - "ip": "34.231.146.236", - "port": 80 - }, - { - "ip": "54.186.10.115", - "port": 80 - }, - { - "ip": "13.127.34.21", - "port": 1337 - }, - { - "ip": "13.127.34.21", - "port": 8080 - }, - { - "ip": "63.35.245.126", - "port": 80 - }, - { - "ip": "65.108.152.247", - "port": 80 - }, - { - "ip": "65.108.152.247", - "port": 8081 - }, - { - "ip": "185.207.107.49", - "port": 80 - }, - { - "ip": "185.207.107.49", - "port": 5000 - }, - { - "ip": "185.207.107.49", - "port": 7801 - }, - { - "ip": "34.247.166.141", - "port": 80 - }, - { - "ip": "44.214.56.114", - "port": 80 - }, - { - "ip": "44.214.56.114", - "port": 443 - }, - { - "ip": "44.214.56.114", - "port": 9001 - }, - { - "ip": "44.214.56.114", - "port": 9002 - }, - { - "ip": "13.58.63.106", - "port": 80 - }, - { - "ip": "13.58.63.106", - "port": 5000 - }, - { - "ip": "13.58.63.106", - "port": 8080 - }, - { - "ip": "13.58.63.106", - "port": 9876 - }, - { - "ip": "211.106.101.85", - "port": 80 - }, - { - "ip": "211.106.101.85", - "port": 8080 - }, - { - "ip": "222.117.17.195", - "port": 80 - }, - { - "ip": "222.117.17.195", - "port": 84 - }, - { - "ip": "222.117.17.195", - "port": 443 - }, - { - "ip": "222.117.17.195", - "port": 8080 - }, - { - "ip": "222.117.17.195", - "port": 9935 - }, - { - "ip": "15.228.179.158", - "port": 4000 - }, - { - "ip": "15.228.179.158", - "port": 6000 - }, - { - "ip": "15.228.179.158", - "port": 6050 - }, - { - "ip": "15.228.179.158", - "port": 7000 - }, - { - "ip": "15.228.179.158", - "port": 7500 - }, - { - "ip": "15.228.179.158", - "port": 7777 - }, - { - "ip": "15.228.179.158", - "port": 8000 - }, - { - "ip": "15.228.179.158", - "port": 8001 - }, - { - "ip": "15.228.179.158", - "port": 8050 - }, - { - "ip": "15.228.179.158", - "port": 8700 - }, - { - "ip": "15.228.179.158", - "port": 9001 - }, - { - "ip": "15.228.179.158", - "port": 9005 - }, - { - "ip": "15.228.179.158", - "port": 9006 - }, - { - "ip": "15.228.179.158", - "port": 9008 - }, - { - "ip": "15.228.179.158", - "port": 9010 - }, - { - "ip": "15.228.179.158", - "port": 9011 - }, - { - "ip": "15.228.179.158", - "port": 9999 - }, - { - "ip": "15.228.179.158", - "port": 30000 - }, - { - "ip": "35.173.205.146", - "port": 80 - }, - { - "ip": "35.173.205.146", - "port": 8080 - }, - { - "ip": "35.173.205.146", - "port": 8081 - }, - { - "ip": "35.173.205.146", - "port": 56789 - }, - { - "ip": "109.74.199.145", - "port": 80 - }, - { - "ip": "109.74.199.145", - "port": 81 - }, - { - "ip": "109.74.199.145", - "port": 443 - }, - { - "ip": "109.74.199.145", - "port": 5000 - }, - { - "ip": "109.74.199.145", - "port": 53412 - }, - { - "ip": "162.241.41.45", - "port": 80 - }, - { - "ip": "162.241.41.45", - "port": 443 - }, - { - "ip": "162.241.41.45", - "port": 2082 - }, - { - "ip": "162.241.41.45", - "port": 2083 - }, - { - "ip": "162.241.41.45", - "port": 2086 - }, - { - "ip": "162.241.41.45", - "port": 2087 - }, - { - "ip": "162.241.41.45", - "port": 2095 - }, - { - "ip": "162.241.41.45", - "port": 2096 - }, - { - "ip": "162.241.41.45", - "port": 3000 - }, - { - "ip": "162.241.41.45", - "port": 3001 - }, - { - "ip": "162.241.41.45", - "port": 3002 - }, - { - "ip": "162.241.41.45", - "port": 3003 - }, - { - "ip": "162.241.41.45", - "port": 3004 - }, - { - "ip": "162.241.41.45", - "port": 3005 - }, - { - "ip": "162.241.41.45", - "port": 3006 - }, - { - "ip": "162.241.41.45", - "port": 3007 - }, - { - "ip": "162.241.41.45", - "port": 3008 - }, - { - "ip": "162.241.41.45", - "port": 3333 - }, - { - "ip": "142.93.237.82", - "port": 443 - }, - { - "ip": "142.93.237.82", - "port": 8000 - }, - { - "ip": "142.93.237.82", - "port": 8080 - }, - { - "ip": "157.245.85.48", - "port": 80 - }, - { - "ip": "157.245.85.48", - "port": 443 - }, - { - "ip": "157.245.85.48", - "port": 3001 - }, - { - "ip": "157.245.85.48", - "port": 9090 - }, - { - "ip": "40.127.12.89", - "port": 80 - }, - { - "ip": "106.246.237.138", - "port": 80 - }, - { - "ip": "106.246.237.138", - "port": 84 - }, - { - "ip": "106.246.237.138", - "port": 8080 - }, - { - "ip": "113.163.202.16", - "port": 80 - }, - { - "ip": "113.163.202.16", - "port": 81 - }, - { - "ip": "113.163.202.16", - "port": 443 - }, - { - "ip": "113.163.202.16", - "port": 4443 - }, - { - "ip": "113.163.202.16", - "port": 4444 - }, - { - "ip": "113.163.202.16", - "port": 6601 - }, - { - "ip": "113.163.202.16", - "port": 8080 - }, - { - "ip": "113.163.202.16", - "port": 8100 - }, - { - "ip": "185.206.147.122", - "port": 80 - }, - { - "ip": "185.206.147.122", - "port": 1337 - }, - { - "ip": "185.206.147.122", - "port": 5000 - }, - { - "ip": "185.206.147.122", - "port": 5008 - }, - { - "ip": "185.206.147.122", - "port": 14131 - }, - { - "ip": "14.225.192.147", - "port": 80 - }, - { - "ip": "14.225.192.147", - "port": 443 - }, - { - "ip": "14.225.192.147", - "port": 1606 - }, - { - "ip": "14.225.192.147", - "port": 3008 - }, - { - "ip": "14.225.192.147", - "port": 3010 - }, - { - "ip": "14.225.192.147", - "port": 3100 - }, - { - "ip": "14.225.192.147", - "port": 3334 - }, - { - "ip": "14.225.192.147", - "port": 8080 - }, - { - "ip": "34.105.6.235", - "port": 5468 - }, - { - "ip": "34.105.6.235", - "port": 5569 - }, - { - "ip": "34.105.6.235", - "port": 5592 - }, - { - "ip": "34.105.6.235", - "port": 5696 - }, - { - "ip": "34.105.6.235", - "port": 5902 - }, - { - "ip": "34.105.6.235", - "port": 5910 - }, - { - "ip": "34.105.6.235", - "port": 6002 - }, - { - "ip": "34.105.6.235", - "port": 6136 - }, - { - "ip": "34.105.6.235", - "port": 6164 - }, - { - "ip": "34.105.6.235", - "port": 6206 - }, - { - "ip": "34.105.6.235", - "port": 6253 - }, - { - "ip": "34.105.6.235", - "port": 6316 - }, - { - "ip": "34.105.6.235", - "port": 6363 - }, - { - "ip": "34.105.6.235", - "port": 6433 - }, - { - "ip": "34.105.6.235", - "port": 6452 - }, - { - "ip": "34.105.6.235", - "port": 6467 - }, - { - "ip": "34.105.6.235", - "port": 6482 - }, - { - "ip": "34.105.6.235", - "port": 6488 - }, - { - "ip": "34.105.6.235", - "port": 6505 - }, - { - "ip": "34.105.6.235", - "port": 6507 - }, - { - "ip": "34.105.6.235", - "port": 6565 - }, - { - "ip": "34.105.6.235", - "port": 6576 - }, - { - "ip": "34.105.6.235", - "port": 6618 - }, - { - "ip": "34.105.6.235", - "port": 6661 - }, - { - "ip": "34.105.6.235", - "port": 6666 - }, - { - "ip": "34.105.6.235", - "port": 6700 - }, - { - "ip": "34.105.6.235", - "port": 7016 - }, - { - "ip": "34.105.6.235", - "port": 7023 - }, - { - "ip": "34.105.6.235", - "port": 7080 - }, - { - "ip": "34.105.6.235", - "port": 7081 - }, - { - "ip": "34.105.6.235", - "port": 7232 - }, - { - "ip": "34.105.6.235", - "port": 7264 - }, - { - "ip": "34.105.6.235", - "port": 7352 - }, - { - "ip": "34.105.6.235", - "port": 7533 - }, - { - "ip": "34.105.6.235", - "port": 7613 - }, - { - "ip": "34.105.6.235", - "port": 7718 - }, - { - "ip": "34.105.6.235", - "port": 7754 - }, - { - "ip": "34.105.6.235", - "port": 7776 - }, - { - "ip": "34.105.6.235", - "port": 7854 - }, - { - "ip": "34.105.6.235", - "port": 7878 - }, - { - "ip": "34.105.6.235", - "port": 7974 - }, - { - "ip": "34.105.6.235", - "port": 7988 - }, - { - "ip": "34.105.6.235", - "port": 7995 - }, - { - "ip": "34.105.6.235", - "port": 7999 - }, - { - "ip": "34.105.6.235", - "port": 8015 - }, - { - "ip": "34.105.6.235", - "port": 8021 - }, - { - "ip": "34.105.6.235", - "port": 8027 - }, - { - "ip": "34.105.6.235", - "port": 8052 - }, - { - "ip": "34.105.6.235", - "port": 8067 - }, - { - "ip": "119.195.100.108", - "port": 80 - }, - { - "ip": "119.195.100.108", - "port": 84 - }, - { - "ip": "119.195.100.108", - "port": 8080 - }, - { - "ip": "119.195.100.108", - "port": 9935 - }, - { - "ip": "112.107.219.74", - "port": 80 - }, - { - "ip": "138.197.99.196", - "port": 80 - }, - { - "ip": "138.197.99.196", - "port": 81 - }, - { - "ip": "138.197.99.196", - "port": 82 - }, - { - "ip": "138.197.99.196", - "port": 83 - }, - { - "ip": "138.197.99.196", - "port": 84 - }, - { - "ip": "138.197.99.196", - "port": 89 - }, - { - "ip": "138.197.99.196", - "port": 99 - }, - { - "ip": "138.197.99.196", - "port": 8080 - }, - { - "ip": "138.197.99.196", - "port": 8089 - }, - { - "ip": "138.197.99.196", - "port": 9082 - }, - { - "ip": "138.197.99.196", - "port": 41084 - }, - { - "ip": "185.180.196.113", - "port": 80 - }, - { - "ip": "185.180.196.113", - "port": 443 - }, - { - "ip": "185.180.196.113", - "port": 5000 - }, - { - "ip": "185.180.196.113", - "port": 7000 - }, - { - "ip": "185.180.196.113", - "port": 8080 - }, - { - "ip": "185.180.196.113", - "port": 8083 - }, - { - "ip": "185.180.196.113", - "port": 9100 - }, - { - "ip": "218.154.132.134", - "port": 80 - }, - { - "ip": "218.154.132.134", - "port": 84 - }, - { - "ip": "218.154.132.134", - "port": 6500 - }, - { - "ip": "218.154.132.134", - "port": 8080 - }, - { - "ip": "218.154.132.134", - "port": 8090 - }, - { - "ip": "54.214.220.95", - "port": 80 - }, - { - "ip": "54.214.220.95", - "port": 8090 - }, - { - "ip": "195.161.68.205", - "port": 80 - }, - { - "ip": "195.161.68.205", - "port": 5245 - }, - { - "ip": "195.161.68.205", - "port": 8080 - }, - { - "ip": "195.161.68.205", - "port": 8888 - }, - { - "ip": "210.183.39.4", - "port": 80 - }, - { - "ip": "210.183.39.4", - "port": 81 - }, - { - "ip": "210.183.39.4", - "port": 84 - }, - { - "ip": "210.183.39.4", - "port": 443 - }, - { - "ip": "210.183.39.4", - "port": 8080 - }, - { - "ip": "210.183.39.4", - "port": 9935 - }, - { - "ip": "47.92.249.102", - "port": 80 - }, - { - "ip": "47.92.249.102", - "port": 8088 - }, - { - "ip": "47.92.249.102", - "port": 8181 - }, - { - "ip": "104.248.9.47", - "port": 80 - }, - { - "ip": "104.248.9.47", - "port": 443 - }, - { - "ip": "104.248.9.47", - "port": 8080 - }, - { - "ip": "150.158.214.132", - "port": 80 - }, - { - "ip": "150.158.214.132", - "port": 443 - }, - { - "ip": "150.158.214.132", - "port": 8080 - }, - { - "ip": "151.248.122.192", - "port": 80 - }, - { - "ip": "151.248.122.192", - "port": 443 - }, - { - "ip": "151.248.122.192", - "port": 1337 - }, - { - "ip": "151.248.122.192", - "port": 1338 - }, - { - "ip": "159.89.98.10", - "port": 8080 - }, - { - "ip": "159.253.18.154", - "port": 80 - }, - { - "ip": "159.253.18.154", - "port": 443 - }, - { - "ip": "159.253.18.154", - "port": 8080 - }, - { - "ip": "159.253.18.154", - "port": 8888 - }, - { - "ip": "47.96.127.87", - "port": 80 - }, - { - "ip": "47.96.127.87", - "port": 443 - }, - { - "ip": "47.96.127.87", - "port": 8888 - }, - { - "ip": "47.96.127.87", - "port": 18088 - }, - { - "ip": "52.87.48.6", - "port": 80 - }, - { - "ip": "188.148.178.234", - "port": 8000 - }, - { - "ip": "188.148.178.234", - "port": 8080 - }, - { - "ip": "34.139.89.181", - "port": 80 - }, - { - "ip": "34.139.89.181", - "port": 8080 - }, - { - "ip": "34.139.89.181", - "port": 8081 - }, - { - "ip": "161.35.207.157", - "port": 80 - }, - { - "ip": "161.35.207.157", - "port": 5000 - }, - { - "ip": "175.215.10.90", - "port": 80 - }, - { - "ip": "175.215.10.90", - "port": 84 - }, - { - "ip": "175.215.10.90", - "port": 6500 - }, - { - "ip": "175.215.10.90", - "port": 8080 - }, - { - "ip": "175.215.10.90", - "port": 8090 - }, - { - "ip": "1.209.195.74", - "port": 80 - }, - { - "ip": "1.209.195.74", - "port": 84 - }, - { - "ip": "1.209.195.74", - "port": 8080 - }, - { - "ip": "46.101.5.103", - "port": 80 - }, - { - "ip": "46.101.5.103", - "port": 443 - }, - { - "ip": "46.101.5.103", - "port": 5000 - }, - { - "ip": "3.36.132.37", - "port": 80 - }, - { - "ip": "3.36.132.37", - "port": 443 - }, - { - "ip": "3.36.132.37", - "port": 5000 - }, - { - "ip": "3.36.132.37", - "port": 5001 - }, - { - "ip": "3.36.132.37", - "port": 40001 - }, - { - "ip": "3.126.200.157", - "port": 80 - }, - { - "ip": "3.126.200.157", - "port": 443 - }, - { - "ip": "3.126.200.157", - "port": 8888 - }, - { - "ip": "13.127.157.75", - "port": 80 - }, - { - "ip": "18.230.190.60", - "port": 4000 - }, - { - "ip": "18.230.190.60", - "port": 4370 - }, - { - "ip": "18.230.190.60", - "port": 6000 - }, - { - "ip": "18.230.190.60", - "port": 6050 - }, - { - "ip": "18.230.190.60", - "port": 7000 - }, - { - "ip": "18.230.190.60", - "port": 7050 - }, - { - "ip": "18.230.190.60", - "port": 7500 - }, - { - "ip": "18.230.190.60", - "port": 7777 - }, - { - "ip": "18.230.190.60", - "port": 8000 - }, - { - "ip": "18.230.190.60", - "port": 8001 - }, - { - "ip": "18.230.190.60", - "port": 8700 - }, - { - "ip": "18.230.190.60", - "port": 9001 - }, - { - "ip": "18.230.190.60", - "port": 9005 - }, - { - "ip": "18.230.190.60", - "port": 9006 - }, - { - "ip": "18.230.190.60", - "port": 9008 - }, - { - "ip": "18.230.190.60", - "port": 9010 - }, - { - "ip": "18.230.190.60", - "port": 9011 - }, - { - "ip": "18.230.190.60", - "port": 9999 - }, - { - "ip": "18.230.190.60", - "port": 30000 - }, - { - "ip": "35.230.9.236", - "port": 5568 - }, - { - "ip": "35.230.9.236", - "port": 5592 - }, - { - "ip": "35.230.9.236", - "port": 5600 - }, - { - "ip": "35.230.9.236", - "port": 5607 - }, - { - "ip": "35.230.9.236", - "port": 5635 - }, - { - "ip": "35.230.9.236", - "port": 5671 - }, - { - "ip": "35.230.9.236", - "port": 5784 - }, - { - "ip": "35.230.9.236", - "port": 5875 - }, - { - "ip": "35.230.9.236", - "port": 5986 - }, - { - "ip": "35.230.9.236", - "port": 6006 - }, - { - "ip": "35.230.9.236", - "port": 6007 - }, - { - "ip": "35.230.9.236", - "port": 6034 - }, - { - "ip": "35.230.9.236", - "port": 6050 - }, - { - "ip": "35.230.9.236", - "port": 6060 - }, - { - "ip": "35.230.9.236", - "port": 6061 - }, - { - "ip": "35.230.9.236", - "port": 6078 - }, - { - "ip": "35.230.9.236", - "port": 6087 - }, - { - "ip": "35.230.9.236", - "port": 6161 - }, - { - "ip": "35.230.9.236", - "port": 6382 - }, - { - "ip": "35.230.9.236", - "port": 6414 - }, - { - "ip": "35.230.9.236", - "port": 6512 - }, - { - "ip": "35.230.9.236", - "port": 6580 - }, - { - "ip": "35.230.9.236", - "port": 6603 - }, - { - "ip": "35.230.9.236", - "port": 6688 - }, - { - "ip": "35.230.9.236", - "port": 6699 - }, - { - "ip": "35.230.9.236", - "port": 6737 - }, - { - "ip": "35.230.9.236", - "port": 6745 - }, - { - "ip": "35.230.9.236", - "port": 6797 - }, - { - "ip": "35.230.9.236", - "port": 6828 - }, - { - "ip": "35.230.9.236", - "port": 6962 - }, - { - "ip": "35.230.9.236", - "port": 7004 - }, - { - "ip": "35.230.9.236", - "port": 7057 - }, - { - "ip": "35.230.9.236", - "port": 7077 - }, - { - "ip": "35.230.9.236", - "port": 7084 - }, - { - "ip": "35.230.9.236", - "port": 7155 - }, - { - "ip": "35.230.9.236", - "port": 7172 - }, - { - "ip": "35.230.9.236", - "port": 7253 - }, - { - "ip": "35.230.9.236", - "port": 7283 - }, - { - "ip": "35.230.9.236", - "port": 7312 - }, - { - "ip": "35.230.9.236", - "port": 7331 - }, - { - "ip": "35.230.9.236", - "port": 7350 - }, - { - "ip": "35.230.9.236", - "port": 7403 - }, - { - "ip": "35.230.9.236", - "port": 7443 - }, - { - "ip": "35.230.9.236", - "port": 7569 - }, - { - "ip": "35.230.9.236", - "port": 7570 - }, - { - "ip": "35.230.9.236", - "port": 7643 - }, - { - "ip": "35.230.9.236", - "port": 7719 - }, - { - "ip": "35.230.9.236", - "port": 7776 - }, - { - "ip": "35.230.9.236", - "port": 7805 - }, - { - "ip": "35.230.9.236", - "port": 7886 - }, - { - "ip": "35.230.9.236", - "port": 8007 - }, - { - "ip": "35.230.9.236", - "port": 8038 - }, - { - "ip": "35.230.9.236", - "port": 8039 - }, - { - "ip": "35.230.9.236", - "port": 8040 - }, - { - "ip": "35.230.9.236", - "port": 8065 - }, - { - "ip": "35.230.9.236", - "port": 8066 - }, - { - "ip": "35.230.9.236", - "port": 8070 - }, - { - "ip": "119.198.52.134", - "port": 80 - }, - { - "ip": "119.198.52.134", - "port": 84 - }, - { - "ip": "119.198.52.134", - "port": 8080 - }, - { - "ip": "119.198.52.134", - "port": 9935 - }, - { - "ip": "157.230.41.150", - "port": 80 - }, - { - "ip": "157.230.41.150", - "port": 443 - }, - { - "ip": "157.230.41.150", - "port": 805 - }, - { - "ip": "157.230.41.150", - "port": 1888 - }, - { - "ip": "157.230.41.150", - "port": 1899 - }, - { - "ip": "157.230.41.150", - "port": 3128 - }, - { - "ip": "157.230.41.150", - "port": 4435 - }, - { - "ip": "157.230.41.150", - "port": 8080 - }, - { - "ip": "157.230.41.150", - "port": 8881 - }, - { - "ip": "157.230.41.150", - "port": 8888 - }, - { - "ip": "157.230.41.150", - "port": 9001 - }, - { - "ip": "192.248.182.108", - "port": 80 - }, - { - "ip": "192.248.182.108", - "port": 81 - }, - { - "ip": "192.248.182.108", - "port": 4892 - }, - { - "ip": "192.248.182.108", - "port": 5335 - }, - { - "ip": "3.128.222.176", - "port": 80 - }, - { - "ip": "35.180.212.27", - "port": 80 - }, - { - "ip": "54.190.217.117", - "port": 6443 - }, - { - "ip": "54.190.217.117", - "port": 8070 - }, - { - "ip": "54.190.217.117", - "port": 8080 - }, - { - "ip": "54.190.217.117", - "port": 8090 - }, - { - "ip": "54.238.8.173", - "port": 80 - }, - { - "ip": "59.20.243.249", - "port": 80 - }, - { - "ip": "59.20.243.249", - "port": 84 - }, - { - "ip": "59.20.243.249", - "port": 8080 - }, - { - "ip": "59.20.243.249", - "port": 9935 - }, - { - "ip": "128.199.233.26", - "port": 80 - }, - { - "ip": "52.43.103.196", - "port": 6443 - }, - { - "ip": "52.43.103.196", - "port": 8070 - }, - { - "ip": "52.43.103.196", - "port": 8090 - }, - { - "ip": "134.195.211.197", - "port": 80 - }, - { - "ip": "134.195.211.197", - "port": 443 - }, - { - "ip": "134.195.211.197", - "port": 888 - }, - { - "ip": "134.195.211.197", - "port": 1200 - }, - { - "ip": "134.195.211.197", - "port": 5212 - }, - { - "ip": "134.195.211.197", - "port": 5244 - }, - { - "ip": "134.195.211.197", - "port": 8014 - }, - { - "ip": "134.195.211.197", - "port": 8080 - }, - { - "ip": "134.195.211.197", - "port": 9090 - }, - { - "ip": "134.195.211.197", - "port": 19999 - }, - { - "ip": "134.195.211.197", - "port": 28080 - }, - { - "ip": "213.188.212.101", - "port": 80 - }, - { - "ip": "16.16.218.62", - "port": 5000 - }, - { - "ip": "16.16.218.62", - "port": 8080 - }, - { - "ip": "43.134.46.175", - "port": 80 - }, - { - "ip": "43.134.46.175", - "port": 443 - }, - { - "ip": "43.134.46.175", - "port": 3002 - }, - { - "ip": "43.134.46.175", - "port": 4000 - }, - { - "ip": "43.134.46.175", - "port": 5210 - }, - { - "ip": "44.228.217.41", - "port": 6443 - }, - { - "ip": "44.228.217.41", - "port": 8070 - }, - { - "ip": "44.228.217.41", - "port": 8080 - }, - { - "ip": "44.228.217.41", - "port": 8090 - }, - { - "ip": "207.180.207.59", - "port": 80 - }, - { - "ip": "207.180.207.59", - "port": 81 - }, - { - "ip": "207.180.207.59", - "port": 443 - }, - { - "ip": "207.180.207.59", - "port": 6969 - }, - { - "ip": "207.180.207.59", - "port": 8084 - }, - { - "ip": "222.120.89.131", - "port": 80 - }, - { - "ip": "222.120.89.131", - "port": 84 - }, - { - "ip": "222.120.89.131", - "port": 443 - }, - { - "ip": "222.120.89.131", - "port": 8080 - }, - { - "ip": "222.120.89.131", - "port": 9935 - }, - { - "ip": "16.170.18.162", - "port": 80 - }, - { - "ip": "16.170.18.162", - "port": 443 - }, - { - "ip": "16.170.18.162", - "port": 3006 - }, - { - "ip": "164.92.170.109", - "port": 80 - }, - { - "ip": "164.92.170.109", - "port": 443 - }, - { - "ip": "164.92.170.109", - "port": 5000 - }, - { - "ip": "121.172.125.189", - "port": 80 - }, - { - "ip": "121.172.125.189", - "port": 84 - }, - { - "ip": "121.172.125.189", - "port": 8080 - }, - { - "ip": "121.172.125.189", - "port": 9935 - }, - { - "ip": "161.189.16.20", - "port": 8080 - }, - { - "ip": "161.189.16.20", - "port": 8088 - }, - { - "ip": "213.239.213.42", - "port": 80 - }, - { - "ip": "213.239.213.42", - "port": 443 - }, - { - "ip": "213.239.213.42", - "port": 3131 - }, - { - "ip": "213.239.213.42", - "port": 5000 - }, - { - "ip": "213.239.213.42", - "port": 5357 - }, - { - "ip": "213.239.213.42", - "port": 5985 - }, - { - "ip": "213.239.213.42", - "port": 47001 - }, - { - "ip": "220.79.239.195", - "port": 80 - }, - { - "ip": "220.79.239.195", - "port": 84 - }, - { - "ip": "220.79.239.195", - "port": 6500 - }, - { - "ip": "220.79.239.195", - "port": 8080 - }, - { - "ip": "220.79.239.195", - "port": 8090 - }, - { - "ip": "15.206.84.109", - "port": 8080 - }, - { - "ip": "51.138.85.184", - "port": 8081 - }, - { - "ip": "108.44.159.64", - "port": 8080 - }, - { - "ip": "108.44.159.64", - "port": 8443 - }, - { - "ip": "135.181.96.11", - "port": 80 - }, - { - "ip": "135.181.96.11", - "port": 443 - }, - { - "ip": "135.181.96.11", - "port": 1080 - }, - { - "ip": "135.181.96.11", - "port": 7492 - }, - { - "ip": "135.181.96.11", - "port": 8080 - }, - { - "ip": "188.225.27.165", - "port": 80 - }, - { - "ip": "188.225.27.165", - "port": 443 - }, - { - "ip": "188.225.27.165", - "port": 8000 - }, - { - "ip": "188.225.27.165", - "port": 8284 - }, - { - "ip": "3.110.128.73", - "port": 80 - }, - { - "ip": "3.110.128.73", - "port": 443 - }, - { - "ip": "3.110.128.73", - "port": 8080 - }, - { - "ip": "3.228.124.13", - "port": 80 - }, - { - "ip": "5.196.6.232", - "port": 80 - }, - { - "ip": "5.196.6.232", - "port": 443 - }, - { - "ip": "5.196.6.232", - "port": 3000 - }, - { - "ip": "5.196.6.232", - "port": 7052 - }, - { - "ip": "35.203.191.34", - "port": 5440 - }, - { - "ip": "35.203.191.34", - "port": 5545 - }, - { - "ip": "35.203.191.34", - "port": 5592 - }, - { - "ip": "35.203.191.34", - "port": 5593 - }, - { - "ip": "35.203.191.34", - "port": 5594 - }, - { - "ip": "35.203.191.34", - "port": 5602 - }, - { - "ip": "35.203.191.34", - "port": 5658 - }, - { - "ip": "35.203.191.34", - "port": 5815 - }, - { - "ip": "35.203.191.34", - "port": 5904 - }, - { - "ip": "35.203.191.34", - "port": 5915 - }, - { - "ip": "35.203.191.34", - "port": 5920 - }, - { - "ip": "35.203.191.34", - "port": 5961 - }, - { - "ip": "35.203.191.34", - "port": 5984 - }, - { - "ip": "35.203.191.34", - "port": 5986 - }, - { - "ip": "35.203.191.34", - "port": 6002 - }, - { - "ip": "35.203.191.34", - "port": 6004 - }, - { - "ip": "35.203.191.34", - "port": 6075 - }, - { - "ip": "35.203.191.34", - "port": 6102 - }, - { - "ip": "35.203.191.34", - "port": 6243 - }, - { - "ip": "35.203.191.34", - "port": 6264 - }, - { - "ip": "35.203.191.34", - "port": 6282 - }, - { - "ip": "35.203.191.34", - "port": 6410 - }, - { - "ip": "35.203.191.34", - "port": 6440 - }, - { - "ip": "35.203.191.34", - "port": 6544 - }, - { - "ip": "35.203.191.34", - "port": 6581 - }, - { - "ip": "35.203.191.34", - "port": 6605 - }, - { - "ip": "35.203.191.34", - "port": 6617 - }, - { - "ip": "35.203.191.34", - "port": 6697 - }, - { - "ip": "35.203.191.34", - "port": 6876 - }, - { - "ip": "35.203.191.34", - "port": 6924 - }, - { - "ip": "35.203.191.34", - "port": 7010 - }, - { - "ip": "35.203.191.34", - "port": 7012 - }, - { - "ip": "35.203.191.34", - "port": 7057 - }, - { - "ip": "35.203.191.34", - "port": 7087 - }, - { - "ip": "35.203.191.34", - "port": 7100 - }, - { - "ip": "35.203.191.34", - "port": 7121 - }, - { - "ip": "35.203.191.34", - "port": 7268 - }, - { - "ip": "35.203.191.34", - "port": 7340 - }, - { - "ip": "35.203.191.34", - "port": 7411 - }, - { - "ip": "35.203.191.34", - "port": 7465 - }, - { - "ip": "35.203.191.34", - "port": 7486 - }, - { - "ip": "35.203.191.34", - "port": 7524 - }, - { - "ip": "35.203.191.34", - "port": 7617 - }, - { - "ip": "35.203.191.34", - "port": 7634 - }, - { - "ip": "35.203.191.34", - "port": 7763 - }, - { - "ip": "35.203.191.34", - "port": 7811 - }, - { - "ip": "35.203.191.34", - "port": 7929 - }, - { - "ip": "35.203.191.34", - "port": 8009 - }, - { - "ip": "35.203.191.34", - "port": 8015 - }, - { - "ip": "35.203.191.34", - "port": 8020 - }, - { - "ip": "35.203.191.34", - "port": 8024 - }, - { - "ip": "35.203.191.34", - "port": 8035 - }, - { - "ip": "35.203.191.34", - "port": 8042 - }, - { - "ip": "35.203.191.34", - "port": 8056 - }, - { - "ip": "35.203.191.34", - "port": 8066 - }, - { - "ip": "83.96.247.128", - "port": 80 - }, - { - "ip": "83.96.247.128", - "port": 443 - }, - { - "ip": "83.96.247.128", - "port": 8080 - }, - { - "ip": "104.199.114.173", - "port": 5494 - }, - { - "ip": "104.199.114.173", - "port": 5590 - }, - { - "ip": "104.199.114.173", - "port": 5601 - }, - { - "ip": "104.199.114.173", - "port": 5701 - }, - { - "ip": "104.199.114.173", - "port": 5804 - }, - { - "ip": "104.199.114.173", - "port": 5892 - }, - { - "ip": "104.199.114.173", - "port": 5906 - }, - { - "ip": "104.199.114.173", - "port": 5908 - }, - { - "ip": "104.199.114.173", - "port": 5913 - }, - { - "ip": "104.199.114.173", - "port": 5935 - }, - { - "ip": "104.199.114.173", - "port": 6008 - }, - { - "ip": "104.199.114.173", - "port": 6080 - }, - { - "ip": "104.199.114.173", - "port": 6188 - }, - { - "ip": "104.199.114.173", - "port": 6209 - }, - { - "ip": "104.199.114.173", - "port": 6251 - }, - { - "ip": "104.199.114.173", - "port": 6294 - }, - { - "ip": "104.199.114.173", - "port": 6331 - }, - { - "ip": "104.199.114.173", - "port": 6362 - }, - { - "ip": "104.199.114.173", - "port": 6433 - }, - { - "ip": "104.199.114.173", - "port": 6609 - }, - { - "ip": "104.199.114.173", - "port": 6697 - }, - { - "ip": "104.199.114.173", - "port": 6699 - }, - { - "ip": "104.199.114.173", - "port": 6701 - }, - { - "ip": "104.199.114.173", - "port": 6755 - }, - { - "ip": "104.199.114.173", - "port": 6783 - }, - { - "ip": "104.199.114.173", - "port": 6895 - }, - { - "ip": "104.199.114.173", - "port": 7018 - }, - { - "ip": "104.199.114.173", - "port": 7077 - }, - { - "ip": "104.199.114.173", - "port": 7090 - }, - { - "ip": "104.199.114.173", - "port": 7373 - }, - { - "ip": "104.199.114.173", - "port": 7415 - }, - { - "ip": "104.199.114.173", - "port": 7433 - }, - { - "ip": "104.199.114.173", - "port": 7458 - }, - { - "ip": "104.199.114.173", - "port": 7499 - }, - { - "ip": "104.199.114.173", - "port": 7687 - }, - { - "ip": "104.199.114.173", - "port": 7759 - }, - { - "ip": "104.199.114.173", - "port": 7780 - }, - { - "ip": "104.199.114.173", - "port": 7799 - }, - { - "ip": "104.199.114.173", - "port": 7948 - }, - { - "ip": "104.199.114.173", - "port": 8007 - }, - { - "ip": "104.199.114.173", - "port": 8015 - }, - { - "ip": "104.199.114.173", - "port": 8019 - }, - { - "ip": "104.199.114.173", - "port": 8020 - }, - { - "ip": "104.199.114.173", - "port": 8024 - }, - { - "ip": "104.199.114.173", - "port": 8025 - }, - { - "ip": "104.199.114.173", - "port": 8041 - }, - { - "ip": "104.199.114.173", - "port": 8060 - }, - { - "ip": "104.199.114.173", - "port": 8062 - }, - { - "ip": "104.199.114.173", - "port": 8075 - }, - { - "ip": "18.191.244.124", - "port": 3128 - }, - { - "ip": "18.191.244.124", - "port": 7777 - }, - { - "ip": "18.191.244.124", - "port": 8000 - }, - { - "ip": "18.191.244.124", - "port": 44444 - }, - { - "ip": "51.178.80.75", - "port": 80 - }, - { - "ip": "51.178.80.75", - "port": 2095 - }, - { - "ip": "51.178.80.75", - "port": 8000 - }, - { - "ip": "51.178.80.75", - "port": 8010 - }, - { - "ip": "51.178.80.75", - "port": 8050 - }, - { - "ip": "51.178.80.75", - "port": 8080 - }, - { - "ip": "51.178.80.75", - "port": 8300 - }, - { - "ip": "51.178.80.75", - "port": 8443 - }, - { - "ip": "51.178.80.75", - "port": 8500 - }, - { - "ip": "51.178.80.75", - "port": 8600 - }, - { - "ip": "51.178.80.75", - "port": 8700 - }, - { - "ip": "134.209.116.116", - "port": 80 - }, - { - "ip": "134.209.116.116", - "port": 443 - }, - { - "ip": "134.209.116.116", - "port": 9191 - }, - { - "ip": "178.128.241.99", - "port": 80 - }, - { - "ip": "178.128.241.99", - "port": 8089 - }, - { - "ip": "222.120.89.129", - "port": 80 - }, - { - "ip": "222.120.89.129", - "port": 84 - }, - { - "ip": "222.120.89.129", - "port": 443 - }, - { - "ip": "222.120.89.129", - "port": 5000 - }, - { - "ip": "222.120.89.129", - "port": 8080 - }, - { - "ip": "43.138.64.131", - "port": 80 - }, - { - "ip": "43.138.64.131", - "port": 443 - }, - { - "ip": "43.138.64.131", - "port": 888 - }, - { - "ip": "43.138.64.131", - "port": 8080 - }, - { - "ip": "51.178.183.168", - "port": 80 - }, - { - "ip": "51.178.183.168", - "port": 443 - }, - { - "ip": "51.178.183.168", - "port": 3000 - }, - { - "ip": "51.178.183.168", - "port": 4243 - }, - { - "ip": "165.227.255.29", - "port": 80 - }, - { - "ip": "165.227.255.29", - "port": 443 - }, - { - "ip": "165.227.255.29", - "port": 3000 - }, - { - "ip": "165.227.255.29", - "port": 3033 - }, - { - "ip": "165.227.255.29", - "port": 3333 - }, - { - "ip": "165.227.255.29", - "port": 5555 - }, - { - "ip": "165.227.255.29", - "port": 8000 - }, - { - "ip": "165.227.255.29", - "port": 8080 - }, - { - "ip": "165.227.255.29", - "port": 9000 - }, - { - "ip": "165.227.255.29", - "port": 9080 - }, - { - "ip": "178.128.181.164", - "port": 80 - }, - { - "ip": "178.128.181.164", - "port": 443 - }, - { - "ip": "178.128.181.164", - "port": 5000 - }, - { - "ip": "115.28.138.35", - "port": 80 - }, - { - "ip": "115.28.138.35", - "port": 4000 - }, - { - "ip": "115.28.138.35", - "port": 8080 - }, - { - "ip": "115.28.138.35", - "port": 8082 - }, - { - "ip": "115.28.138.35", - "port": 8083 - }, - { - "ip": "115.28.138.35", - "port": 8866 - }, - { - "ip": "118.189.204.126", - "port": 80 - }, - { - "ip": "118.189.204.126", - "port": 443 - }, - { - "ip": "118.189.204.126", - "port": 1880 - }, - { - "ip": "118.189.204.126", - "port": 4430 - }, - { - "ip": "118.189.204.126", - "port": 5000 - }, - { - "ip": "118.189.204.126", - "port": 5001 - }, - { - "ip": "118.189.204.126", - "port": 5004 - }, - { - "ip": "118.189.204.126", - "port": 5006 - }, - { - "ip": "118.189.204.126", - "port": 5009 - }, - { - "ip": "118.189.204.126", - "port": 5010 - }, - { - "ip": "118.189.204.126", - "port": 5014 - }, - { - "ip": "118.189.204.126", - "port": 8081 - }, - { - "ip": "118.189.204.126", - "port": 8123 - }, - { - "ip": "118.189.204.126", - "port": 9000 - }, - { - "ip": "118.189.204.126", - "port": 30080 - }, - { - "ip": "118.189.204.126", - "port": 50001 - }, - { - "ip": "118.189.204.126", - "port": 50002 - }, - { - "ip": "139.59.9.203", - "port": 80 - }, - { - "ip": "139.59.9.203", - "port": 83 - }, - { - "ip": "139.59.9.203", - "port": 85 - }, - { - "ip": "139.59.9.203", - "port": 90 - }, - { - "ip": "139.59.9.203", - "port": 92 - }, - { - "ip": "139.59.9.203", - "port": 3000 - }, - { - "ip": "139.59.9.203", - "port": 8000 - }, - { - "ip": "34.225.29.16", - "port": 80 - }, - { - "ip": "34.232.103.226", - "port": 80 - }, - { - "ip": "44.204.141.44", - "port": 8080 - }, - { - "ip": "66.226.74.217", - "port": 80 - }, - { - "ip": "66.226.74.217", - "port": 443 - }, - { - "ip": "66.226.74.217", - "port": 3000 - }, - { - "ip": "66.226.74.217", - "port": 4502 - }, - { - "ip": "66.226.74.217", - "port": 8080 - }, - { - "ip": "66.226.74.217", - "port": 10000 - }, - { - "ip": "121.173.159.66", - "port": 80 - }, - { - "ip": "121.173.159.66", - "port": 84 - }, - { - "ip": "121.173.159.66", - "port": 8080 - }, - { - "ip": "121.173.159.66", - "port": 9935 - }, - { - "ip": "142.93.139.149", - "port": 80 - }, - { - "ip": "142.93.139.149", - "port": 443 - }, - { - "ip": "142.93.139.149", - "port": 3000 - }, - { - "ip": "142.93.139.149", - "port": 3002 - }, - { - "ip": "142.93.139.149", - "port": 5001 - }, - { - "ip": "142.93.139.149", - "port": 6000 - }, - { - "ip": "185.103.155.163", - "port": 80 - }, - { - "ip": "185.103.155.163", - "port": 443 - }, - { - "ip": "185.103.155.163", - "port": 8080 - }, - { - "ip": "185.103.155.163", - "port": 8082 - }, - { - "ip": "185.103.155.163", - "port": 8083 - }, - { - "ip": "185.103.155.163", - "port": 61772 - }, - { - "ip": "62.210.190.77", - "port": 80 - }, - { - "ip": "62.210.190.77", - "port": 443 - }, - { - "ip": "62.210.190.77", - "port": 3000 - }, - { - "ip": "62.210.190.77", - "port": 3010 - }, - { - "ip": "62.210.190.77", - "port": 8080 - }, - { - "ip": "62.210.190.77", - "port": 8099 - }, - { - "ip": "62.210.190.77", - "port": 28659 - }, - { - "ip": "62.210.190.77", - "port": 29926 - }, - { - "ip": "188.166.67.75", - "port": 80 - }, - { - "ip": "188.166.67.75", - "port": 9001 - }, - { - "ip": "198.23.228.188", - "port": 80 - }, - { - "ip": "198.23.228.188", - "port": 8080 - }, - { - "ip": "198.23.228.188", - "port": 10000 - }, - { - "ip": "34.83.76.188", - "port": 5433 - }, - { - "ip": "34.83.76.188", - "port": 5494 - }, - { - "ip": "34.83.76.188", - "port": 5503 - }, - { - "ip": "34.83.76.188", - "port": 5561 - }, - { - "ip": "34.83.76.188", - "port": 5569 - }, - { - "ip": "34.83.76.188", - "port": 5609 - }, - { - "ip": "34.83.76.188", - "port": 5640 - }, - { - "ip": "34.83.76.188", - "port": 5672 - }, - { - "ip": "34.83.76.188", - "port": 5678 - }, - { - "ip": "34.83.76.188", - "port": 5739 - }, - { - "ip": "34.83.76.188", - "port": 5811 - }, - { - "ip": "34.83.76.188", - "port": 5835 - }, - { - "ip": "34.83.76.188", - "port": 5907 - }, - { - "ip": "34.83.76.188", - "port": 5908 - }, - { - "ip": "34.83.76.188", - "port": 5915 - }, - { - "ip": "34.83.76.188", - "port": 5917 - }, - { - "ip": "34.83.76.188", - "port": 5990 - }, - { - "ip": "34.83.76.188", - "port": 6010 - }, - { - "ip": "34.83.76.188", - "port": 6078 - }, - { - "ip": "34.83.76.188", - "port": 6120 - }, - { - "ip": "34.83.76.188", - "port": 6161 - }, - { - "ip": "34.83.76.188", - "port": 6296 - }, - { - "ip": "34.83.76.188", - "port": 6305 - }, - { - "ip": "34.83.76.188", - "port": 6441 - }, - { - "ip": "34.83.76.188", - "port": 6521 - }, - { - "ip": "34.83.76.188", - "port": 6532 - }, - { - "ip": "34.83.76.188", - "port": 6540 - }, - { - "ip": "34.83.76.188", - "port": 6769 - }, - { - "ip": "34.83.76.188", - "port": 6779 - }, - { - "ip": "34.83.76.188", - "port": 6897 - }, - { - "ip": "34.83.76.188", - "port": 6969 - }, - { - "ip": "34.83.76.188", - "port": 6996 - }, - { - "ip": "34.83.76.188", - "port": 7001 - }, - { - "ip": "34.83.76.188", - "port": 7002 - }, - { - "ip": "34.83.76.188", - "port": 7010 - }, - { - "ip": "34.83.76.188", - "port": 7100 - }, - { - "ip": "34.83.76.188", - "port": 7231 - }, - { - "ip": "34.83.76.188", - "port": 7318 - }, - { - "ip": "34.83.76.188", - "port": 7325 - }, - { - "ip": "34.83.76.188", - "port": 7375 - }, - { - "ip": "34.83.76.188", - "port": 7496 - }, - { - "ip": "34.83.76.188", - "port": 7503 - }, - { - "ip": "34.83.76.188", - "port": 7698 - }, - { - "ip": "34.83.76.188", - "port": 7726 - }, - { - "ip": "34.83.76.188", - "port": 7771 - }, - { - "ip": "34.83.76.188", - "port": 7780 - }, - { - "ip": "34.83.76.188", - "port": 7794 - }, - { - "ip": "34.83.76.188", - "port": 7822 - }, - { - "ip": "34.83.76.188", - "port": 7830 - }, - { - "ip": "34.83.76.188", - "port": 7834 - }, - { - "ip": "34.83.76.188", - "port": 7838 - }, - { - "ip": "34.83.76.188", - "port": 8002 - }, - { - "ip": "34.83.76.188", - "port": 8007 - }, - { - "ip": "34.83.76.188", - "port": 8010 - }, - { - "ip": "34.83.76.188", - "port": 8017 - }, - { - "ip": "34.83.76.188", - "port": 8036 - }, - { - "ip": "34.83.76.188", - "port": 8051 - }, - { - "ip": "34.83.76.188", - "port": 8052 - }, - { - "ip": "34.83.76.188", - "port": 8056 - }, - { - "ip": "34.83.76.188", - "port": 8058 - }, - { - "ip": "34.83.76.188", - "port": 8061 - }, - { - "ip": "34.83.76.188", - "port": 8065 - }, - { - "ip": "34.83.76.188", - "port": 8069 - }, - { - "ip": "49.234.126.170", - "port": 80 - }, - { - "ip": "49.234.126.170", - "port": 443 - }, - { - "ip": "49.234.126.170", - "port": 8081 - }, - { - "ip": "52.83.212.59", - "port": 80 - }, - { - "ip": "52.83.212.59", - "port": 443 - }, - { - "ip": "52.83.212.59", - "port": 6261 - }, - { - "ip": "52.83.212.59", - "port": 6262 - }, - { - "ip": "52.83.212.59", - "port": 8000 - }, - { - "ip": "52.83.212.59", - "port": 8001 - }, - { - "ip": "52.83.212.59", - "port": 8180 - }, - { - "ip": "52.83.212.59", - "port": 8280 - }, - { - "ip": "52.83.212.59", - "port": 8800 - }, - { - "ip": "52.83.212.59", - "port": 8880 - }, - { - "ip": "52.83.212.59", - "port": 8888 - }, - { - "ip": "52.83.212.59", - "port": 9100 - }, - { - "ip": "52.83.212.59", - "port": 9101 - }, - { - "ip": "59.27.41.6", - "port": 84 - }, - { - "ip": "59.27.41.6", - "port": 443 - }, - { - "ip": "59.27.41.6", - "port": 8080 - }, - { - "ip": "59.27.41.6", - "port": 9935 - }, - { - "ip": "116.82.84.110", - "port": 80 - }, - { - "ip": "116.82.84.110", - "port": 443 - }, - { - "ip": "116.82.84.110", - "port": 3000 - }, - { - "ip": "116.82.84.110", - "port": 5001 - }, - { - "ip": "116.82.84.110", - "port": 5003 - }, - { - "ip": "116.82.84.110", - "port": 7547 - }, - { - "ip": "116.82.84.110", - "port": 8080 - }, - { - "ip": "116.82.84.110", - "port": 8443 - }, - { - "ip": "116.82.84.110", - "port": 49153 - }, - { - "ip": "157.230.33.146", - "port": 80 - }, - { - "ip": "157.230.33.146", - "port": 443 - }, - { - "ip": "157.230.33.146", - "port": 8080 - }, - { - "ip": "157.230.33.146", - "port": 8082 - }, - { - "ip": "157.230.33.146", - "port": 9000 - }, - { - "ip": "157.230.33.146", - "port": 30080 - }, - { - "ip": "157.245.6.190", - "port": 80 - }, - { - "ip": "157.245.6.190", - "port": 443 - }, - { - "ip": "157.245.6.190", - "port": 5000 - }, - { - "ip": "3.16.213.24", - "port": 80 - }, - { - "ip": "3.16.213.24", - "port": 1337 - }, - { - "ip": "3.16.213.24", - "port": 3001 - }, - { - "ip": "59.10.71.130", - "port": 80 - }, - { - "ip": "59.10.71.130", - "port": 84 - }, - { - "ip": "59.10.71.130", - "port": 8080 - }, - { - "ip": "59.10.71.130", - "port": 9935 - }, - { - "ip": "61.32.69.218", - "port": 80 - }, - { - "ip": "61.32.69.218", - "port": 81 - }, - { - "ip": "61.32.69.218", - "port": 443 - }, - { - "ip": "61.32.69.218", - "port": 8080 - }, - { - "ip": "119.145.129.194", - "port": 80 - }, - { - "ip": "119.145.129.194", - "port": 82 - }, - { - "ip": "119.145.129.194", - "port": 443 - }, - { - "ip": "119.145.129.194", - "port": 3159 - }, - { - "ip": "119.145.129.194", - "port": 4482 - }, - { - "ip": "119.145.129.194", - "port": 4483 - }, - { - "ip": "119.145.129.194", - "port": 5001 - }, - { - "ip": "119.145.129.194", - "port": 5289 - }, - { - "ip": "119.145.129.194", - "port": 5904 - }, - { - "ip": "119.145.129.194", - "port": 5909 - }, - { - "ip": "119.145.129.194", - "port": 6002 - }, - { - "ip": "119.145.129.194", - "port": 7002 - }, - { - "ip": "119.145.129.194", - "port": 7003 - }, - { - "ip": "119.145.129.194", - "port": 8061 - }, - { - "ip": "119.145.129.194", - "port": 8062 - }, - { - "ip": "119.145.129.194", - "port": 8064 - }, - { - "ip": "119.145.129.194", - "port": 8066 - }, - { - "ip": "119.145.129.194", - "port": 8074 - }, - { - "ip": "119.145.129.194", - "port": 8081 - }, - { - "ip": "119.145.129.194", - "port": 8082 - }, - { - "ip": "119.145.129.194", - "port": 8083 - }, - { - "ip": "119.145.129.194", - "port": 8084 - }, - { - "ip": "119.145.129.194", - "port": 8085 - }, - { - "ip": "119.145.129.194", - "port": 8092 - }, - { - "ip": "119.145.129.194", - "port": 8093 - }, - { - "ip": "119.145.129.194", - "port": 8094 - }, - { - "ip": "119.145.129.194", - "port": 8095 - }, - { - "ip": "119.145.129.194", - "port": 8097 - }, - { - "ip": "119.145.129.194", - "port": 8161 - }, - { - "ip": "119.145.129.194", - "port": 8180 - }, - { - "ip": "119.145.129.194", - "port": 8184 - }, - { - "ip": "119.145.129.194", - "port": 8185 - }, - { - "ip": "119.145.129.194", - "port": 8235 - }, - { - "ip": "119.145.129.194", - "port": 8280 - }, - { - "ip": "119.145.129.194", - "port": 8282 - }, - { - "ip": "119.145.129.194", - "port": 8533 - }, - { - "ip": "119.145.129.194", - "port": 8535 - }, - { - "ip": "119.145.129.194", - "port": 8536 - }, - { - "ip": "119.145.129.194", - "port": 8537 - }, - { - "ip": "119.145.129.194", - "port": 8538 - }, - { - "ip": "119.145.129.194", - "port": 8585 - }, - { - "ip": "119.145.129.194", - "port": 8586 - }, - { - "ip": "119.145.129.194", - "port": 8806 - }, - { - "ip": "119.145.129.194", - "port": 8851 - }, - { - "ip": "119.145.129.194", - "port": 8882 - }, - { - "ip": "119.145.129.194", - "port": 8891 - }, - { - "ip": "119.145.129.194", - "port": 9000 - }, - { - "ip": "119.145.129.194", - "port": 9015 - }, - { - "ip": "119.145.129.194", - "port": 9060 - }, - { - "ip": "119.145.129.194", - "port": 9066 - }, - { - "ip": "119.145.129.194", - "port": 9070 - }, - { - "ip": "119.145.129.194", - "port": 9078 - }, - { - "ip": "119.145.129.194", - "port": 9080 - }, - { - "ip": "119.145.129.194", - "port": 9084 - }, - { - "ip": "119.145.129.194", - "port": 9085 - }, - { - "ip": "119.145.129.194", - "port": 9090 - }, - { - "ip": "119.145.129.194", - "port": 9091 - }, - { - "ip": "119.145.129.194", - "port": 9093 - }, - { - "ip": "119.145.129.194", - "port": 9099 - }, - { - "ip": "119.145.129.194", - "port": 9100 - }, - { - "ip": "119.145.129.194", - "port": 9140 - }, - { - "ip": "119.145.129.194", - "port": 9160 - }, - { - "ip": "119.145.129.194", - "port": 9901 - }, - { - "ip": "119.145.129.194", - "port": 9990 - }, - { - "ip": "119.145.129.194", - "port": 10080 - }, - { - "ip": "119.145.129.194", - "port": 10200 - }, - { - "ip": "119.145.129.194", - "port": 12121 - }, - { - "ip": "119.145.129.194", - "port": 12390 - }, - { - "ip": "119.145.129.194", - "port": 16071 - }, - { - "ip": "119.145.129.194", - "port": 20500 - }, - { - "ip": "119.145.129.194", - "port": 30011 - }, - { - "ip": "5.78.98.54", - "port": 80 - }, - { - "ip": "5.78.98.54", - "port": 81 - }, - { - "ip": "5.78.98.54", - "port": 443 - }, - { - "ip": "5.78.98.54", - "port": 8080 - }, - { - "ip": "5.78.98.54", - "port": 50001 - }, - { - "ip": "5.78.98.54", - "port": 50002 - }, - { - "ip": "52.149.157.55", - "port": 80 - }, - { - "ip": "52.149.157.55", - "port": 443 - }, - { - "ip": "52.149.157.55", - "port": 3000 - }, - { - "ip": "52.149.157.55", - "port": 8040 - }, - { - "ip": "52.149.157.55", - "port": 8083 - }, - { - "ip": "3.13.219.45", - "port": 80 - }, - { - "ip": "3.13.219.45", - "port": 8000 - }, - { - "ip": "35.167.142.80", - "port": 80 - }, - { - "ip": "54.155.194.150", - "port": 80 - }, - { - "ip": "144.91.102.214", - "port": 80 - }, - { - "ip": "144.91.102.214", - "port": 443 - }, - { - "ip": "144.91.102.214", - "port": 8079 - }, - { - "ip": "144.91.102.214", - "port": 8082 - }, - { - "ip": "200.170.211.118", - "port": 150 - }, - { - "ip": "200.170.211.118", - "port": 222 - }, - { - "ip": "200.170.211.118", - "port": 1012 - }, - { - "ip": "200.170.211.118", - "port": 1406 - }, - { - "ip": "200.170.211.118", - "port": 1444 - }, - { - "ip": "200.170.211.118", - "port": 1634 - }, - { - "ip": "200.170.211.118", - "port": 2083 - }, - { - "ip": "200.170.211.118", - "port": 3146 - }, - { - "ip": "200.170.211.118", - "port": 8091 - }, - { - "ip": "200.170.211.118", - "port": 8092 - }, - { - "ip": "200.170.211.118", - "port": 8094 - }, - { - "ip": "200.170.211.118", - "port": 8121 - }, - { - "ip": "200.170.211.118", - "port": 8122 - }, - { - "ip": "200.170.211.118", - "port": 8131 - }, - { - "ip": "200.170.211.118", - "port": 8132 - }, - { - "ip": "200.170.211.118", - "port": 8133 - }, - { - "ip": "200.170.211.118", - "port": 8170 - }, - { - "ip": "200.170.211.118", - "port": 8171 - }, - { - "ip": "200.170.211.118", - "port": 8173 - }, - { - "ip": "200.170.211.118", - "port": 8174 - }, - { - "ip": "200.170.211.118", - "port": 8175 - }, - { - "ip": "200.170.211.118", - "port": 8176 - }, - { - "ip": "200.170.211.118", - "port": 8177 - }, - { - "ip": "200.170.211.118", - "port": 8178 - }, - { - "ip": "200.170.211.118", - "port": 8181 - }, - { - "ip": "200.170.211.118", - "port": 8182 - }, - { - "ip": "200.170.211.118", - "port": 8183 - }, - { - "ip": "200.170.211.118", - "port": 8184 - }, - { - "ip": "200.170.211.118", - "port": 8185 - }, - { - "ip": "200.170.211.118", - "port": 8190 - }, - { - "ip": "200.170.211.118", - "port": 8191 - }, - { - "ip": "200.170.211.118", - "port": 8192 - }, - { - "ip": "200.170.211.118", - "port": 8193 - }, - { - "ip": "200.170.211.118", - "port": 8194 - }, - { - "ip": "200.170.211.118", - "port": 8195 - }, - { - "ip": "200.170.211.118", - "port": 8196 - }, - { - "ip": "200.170.211.118", - "port": 8203 - }, - { - "ip": "200.170.211.118", - "port": 9999 - }, - { - "ip": "200.170.211.118", - "port": 10000 - }, - { - "ip": "200.170.211.118", - "port": 10012 - }, - { - "ip": "200.170.211.118", - "port": 10013 - }, - { - "ip": "200.170.211.118", - "port": 10014 - }, - { - "ip": "200.170.211.118", - "port": 10015 - }, - { - "ip": "200.170.211.118", - "port": 10016 - }, - { - "ip": "200.170.211.118", - "port": 10017 - }, - { - "ip": "200.170.211.118", - "port": 10018 - }, - { - "ip": "200.170.211.118", - "port": 10101 - }, - { - "ip": "200.170.211.118", - "port": 10106 - }, - { - "ip": "200.170.211.118", - "port": 10109 - }, - { - "ip": "200.170.211.118", - "port": 10129 - }, - { - "ip": "200.170.211.118", - "port": 21063 - }, - { - "ip": "200.170.211.118", - "port": 25013 - }, - { - "ip": "200.170.211.118", - "port": 40015 - }, - { - "ip": "200.170.211.118", - "port": 61234 - }, - { - "ip": "1.224.146.199", - "port": 80 - }, - { - "ip": "1.224.146.199", - "port": 443 - }, - { - "ip": "1.224.146.199", - "port": 2210 - }, - { - "ip": "1.224.146.199", - "port": 5000 - }, - { - "ip": "1.224.146.199", - "port": 5001 - }, - { - "ip": "54.176.163.67", - "port": 80 - }, - { - "ip": "161.156.161.8", - "port": 80 - }, - { - "ip": "161.156.161.8", - "port": 8081 - }, - { - "ip": "161.156.161.8", - "port": 8082 - }, - { - "ip": "161.156.161.8", - "port": 8085 - }, - { - "ip": "161.156.161.8", - "port": 8989 - }, - { - "ip": "168.138.201.144", - "port": 8080 - }, - { - "ip": "206.189.0.55", - "port": 80 - }, - { - "ip": "206.189.0.55", - "port": 443 - }, - { - "ip": "206.189.0.55", - "port": 3838 - }, - { - "ip": "3.13.219.45", - "port": 80 - }, - { - "ip": "3.13.219.45", - "port": 8000 - }, - { - "ip": "14.51.246.40", - "port": 80 - }, - { - "ip": "14.51.246.40", - "port": 81 - }, - { - "ip": "14.51.246.40", - "port": 84 - }, - { - "ip": "14.51.246.40", - "port": 443 - }, - { - "ip": "14.51.246.40", - "port": 8080 - }, - { - "ip": "14.51.246.40", - "port": 9935 - }, - { - "ip": "54.94.86.34", - "port": 4000 - }, - { - "ip": "54.94.86.34", - "port": 4372 - }, - { - "ip": "54.94.86.34", - "port": 6000 - }, - { - "ip": "54.94.86.34", - "port": 6050 - }, - { - "ip": "54.94.86.34", - "port": 7000 - }, - { - "ip": "54.94.86.34", - "port": 7050 - }, - { - "ip": "54.94.86.34", - "port": 7500 - }, - { - "ip": "54.94.86.34", - "port": 7777 - }, - { - "ip": "54.94.86.34", - "port": 8000 - }, - { - "ip": "54.94.86.34", - "port": 8001 - }, - { - "ip": "54.94.86.34", - "port": 8050 - }, - { - "ip": "54.94.86.34", - "port": 8700 - }, - { - "ip": "54.94.86.34", - "port": 9001 - }, - { - "ip": "54.94.86.34", - "port": 9005 - }, - { - "ip": "54.94.86.34", - "port": 9006 - }, - { - "ip": "54.94.86.34", - "port": 9008 - }, - { - "ip": "54.94.86.34", - "port": 9010 - }, - { - "ip": "54.94.86.34", - "port": 9011 - }, - { - "ip": "54.94.86.34", - "port": 9999 - }, - { - "ip": "54.94.86.34", - "port": 30000 - }, - { - "ip": "176.115.151.13", - "port": 80 - }, - { - "ip": "176.115.151.13", - "port": 443 - }, - { - "ip": "176.115.151.13", - "port": 8085 - }, - { - "ip": "1.221.230.91", - "port": 80 - }, - { - "ip": "1.221.230.91", - "port": 81 - }, - { - "ip": "1.221.230.91", - "port": 443 - }, - { - "ip": "1.221.230.91", - "port": 4856 - }, - { - "ip": "1.221.230.91", - "port": 5000 - }, - { - "ip": "1.221.230.91", - "port": 5050 - }, - { - "ip": "1.221.230.91", - "port": 8080 - }, - { - "ip": "1.221.230.91", - "port": 10084 - }, - { - "ip": "1.221.230.91", - "port": 18080 - }, - { - "ip": "1.221.230.91", - "port": 20084 - }, - { - "ip": "54.214.192.247", - "port": 5000 - }, - { - "ip": "108.128.39.221", - "port": 80 - }, - { - "ip": "108.128.39.221", - "port": 5432 - }, - { - "ip": "121.173.218.168", - "port": 80 - }, - { - "ip": "121.173.218.168", - "port": 8080 - }, - { - "ip": "139.196.255.220", - "port": 80 - }, - { - "ip": "139.196.255.220", - "port": 8090 - }, - { - "ip": "139.196.255.220", - "port": 8880 - }, - { - "ip": "139.196.255.220", - "port": 8882 - }, - { - "ip": "139.196.255.220", - "port": 8884 - }, - { - "ip": "139.196.255.220", - "port": 8885 - }, - { - "ip": "139.196.255.220", - "port": 8888 - }, - { - "ip": "139.196.255.220", - "port": 9981 - }, - { - "ip": "139.196.255.220", - "port": 21000 - }, - { - "ip": "139.196.255.220", - "port": 21007 - }, - { - "ip": "139.196.255.220", - "port": 21009 - }, - { - "ip": "139.196.255.220", - "port": 21086 - }, - { - "ip": "139.196.255.220", - "port": 21100 - }, - { - "ip": "139.196.255.220", - "port": 21101 - }, - { - "ip": "35.197.103.96", - "port": 5602 - }, - { - "ip": "35.197.103.96", - "port": 5736 - }, - { - "ip": "35.197.103.96", - "port": 5915 - }, - { - "ip": "35.197.103.96", - "port": 5920 - }, - { - "ip": "35.197.103.96", - "port": 5938 - }, - { - "ip": "35.197.103.96", - "port": 5984 - }, - { - "ip": "35.197.103.96", - "port": 5987 - }, - { - "ip": "35.197.103.96", - "port": 6363 - }, - { - "ip": "35.197.103.96", - "port": 6405 - }, - { - "ip": "35.197.103.96", - "port": 6415 - }, - { - "ip": "35.197.103.96", - "port": 6544 - }, - { - "ip": "35.197.103.96", - "port": 6581 - }, - { - "ip": "35.197.103.96", - "port": 6590 - }, - { - "ip": "35.197.103.96", - "port": 6659 - }, - { - "ip": "35.197.103.96", - "port": 6781 - }, - { - "ip": "35.197.103.96", - "port": 6865 - }, - { - "ip": "35.197.103.96", - "port": 6979 - }, - { - "ip": "35.197.103.96", - "port": 7004 - }, - { - "ip": "35.197.103.96", - "port": 7078 - }, - { - "ip": "35.197.103.96", - "port": 7086 - }, - { - "ip": "35.197.103.96", - "port": 7088 - }, - { - "ip": "35.197.103.96", - "port": 7090 - }, - { - "ip": "35.197.103.96", - "port": 7220 - }, - { - "ip": "35.197.103.96", - "port": 7302 - }, - { - "ip": "35.197.103.96", - "port": 7323 - }, - { - "ip": "35.197.103.96", - "port": 7676 - }, - { - "ip": "35.197.103.96", - "port": 7691 - }, - { - "ip": "35.197.103.96", - "port": 7700 - }, - { - "ip": "35.197.103.96", - "port": 7777 - }, - { - "ip": "35.197.103.96", - "port": 7782 - }, - { - "ip": "35.197.103.96", - "port": 7884 - }, - { - "ip": "35.197.103.96", - "port": 7900 - }, - { - "ip": "35.197.103.96", - "port": 7999 - }, - { - "ip": "35.197.103.96", - "port": 8008 - }, - { - "ip": "35.197.103.96", - "port": 8026 - }, - { - "ip": "35.197.103.96", - "port": 8027 - }, - { - "ip": "35.197.103.96", - "port": 8028 - }, - { - "ip": "35.197.103.96", - "port": 8030 - }, - { - "ip": "35.197.103.96", - "port": 8033 - }, - { - "ip": "35.197.103.96", - "port": 8066 - }, - { - "ip": "35.197.103.96", - "port": 8069 - }, - { - "ip": "35.197.103.96", - "port": 8072 - }, - { - "ip": "35.197.103.96", - "port": 8073 - }, - { - "ip": "46.101.200.151", - "port": 80 - }, - { - "ip": "46.101.200.151", - "port": 443 - }, - { - "ip": "46.101.200.151", - "port": 3000 - }, - { - "ip": "46.101.200.151", - "port": 3100 - }, - { - "ip": "46.101.200.151", - "port": 4000 - }, - { - "ip": "46.101.200.151", - "port": 8000 - }, - { - "ip": "46.101.200.151", - "port": 8080 - }, - { - "ip": "52.203.226.194", - "port": 80 - }, - { - "ip": "52.203.226.194", - "port": 443 - }, - { - "ip": "52.203.226.194", - "port": 8080 - }, - { - "ip": "165.22.103.95", - "port": 80 - }, - { - "ip": "165.22.103.95", - "port": 8080 - }, - { - "ip": "35.158.113.90", - "port": 8080 - }, - { - "ip": "35.197.17.247", - "port": 5544 - }, - { - "ip": "35.197.17.247", - "port": 5568 - }, - { - "ip": "35.197.17.247", - "port": 5575 - }, - { - "ip": "35.197.17.247", - "port": 5576 - }, - { - "ip": "35.197.17.247", - "port": 5594 - }, - { - "ip": "35.197.17.247", - "port": 5675 - }, - { - "ip": "35.197.17.247", - "port": 5842 - }, - { - "ip": "35.197.17.247", - "port": 5870 - }, - { - "ip": "35.197.17.247", - "port": 5902 - }, - { - "ip": "35.197.17.247", - "port": 5984 - }, - { - "ip": "35.197.17.247", - "port": 5986 - }, - { - "ip": "35.197.17.247", - "port": 5987 - }, - { - "ip": "35.197.17.247", - "port": 5991 - }, - { - "ip": "35.197.17.247", - "port": 5996 - }, - { - "ip": "35.197.17.247", - "port": 5997 - }, - { - "ip": "35.197.17.247", - "port": 6036 - }, - { - "ip": "35.197.17.247", - "port": 6161 - }, - { - "ip": "35.197.17.247", - "port": 6365 - }, - { - "ip": "35.197.17.247", - "port": 6426 - }, - { - "ip": "35.197.17.247", - "port": 6440 - }, - { - "ip": "35.197.17.247", - "port": 6565 - }, - { - "ip": "35.197.17.247", - "port": 6580 - }, - { - "ip": "35.197.17.247", - "port": 6605 - }, - { - "ip": "35.197.17.247", - "port": 7068 - }, - { - "ip": "35.197.17.247", - "port": 7175 - }, - { - "ip": "35.197.17.247", - "port": 7289 - }, - { - "ip": "35.197.17.247", - "port": 7348 - }, - { - "ip": "35.197.17.247", - "port": 7491 - }, - { - "ip": "35.197.17.247", - "port": 7537 - }, - { - "ip": "35.197.17.247", - "port": 7605 - }, - { - "ip": "35.197.17.247", - "port": 7633 - }, - { - "ip": "35.197.17.247", - "port": 7704 - }, - { - "ip": "35.197.17.247", - "port": 7775 - }, - { - "ip": "35.197.17.247", - "port": 7900 - }, - { - "ip": "35.197.17.247", - "port": 7946 - }, - { - "ip": "35.197.17.247", - "port": 8000 - }, - { - "ip": "35.197.17.247", - "port": 8001 - }, - { - "ip": "35.197.17.247", - "port": 8006 - }, - { - "ip": "35.197.17.247", - "port": 8047 - }, - { - "ip": "35.197.17.247", - "port": 8069 - }, - { - "ip": "52.53.135.208", - "port": 80 - }, - { - "ip": "54.148.165.239", - "port": 5000 - }, - { - "ip": "154.12.55.62", - "port": 443 - }, - { - "ip": "154.12.55.62", - "port": 888 - }, - { - "ip": "154.12.55.62", - "port": 8080 - }, - { - "ip": "154.12.55.62", - "port": 8888 - }, - { - "ip": "3.23.227.85", - "port": 80 - }, - { - "ip": "13.53.62.239", - "port": 80 - }, - { - "ip": "13.53.62.239", - "port": 443 - }, - { - "ip": "13.53.62.239", - "port": 8080 - }, - { - "ip": "139.59.99.138", - "port": 80 - }, - { - "ip": "139.59.99.138", - "port": 10250 - }, - { - "ip": "139.59.99.138", - "port": 10256 - }, - { - "ip": "139.59.99.138", - "port": 30002 - }, - { - "ip": "139.59.99.138", - "port": 30003 - }, - { - "ip": "139.59.99.138", - "port": 30005 - }, - { - "ip": "139.59.99.138", - "port": 30006 - }, - { - "ip": "139.59.99.138", - "port": 30008 - }, - { - "ip": "139.59.99.138", - "port": 30009 - }, - { - "ip": "139.59.99.138", - "port": 30010 - }, - { - "ip": "139.59.99.138", - "port": 30011 - }, - { - "ip": "139.59.99.138", - "port": 30012 - }, - { - "ip": "139.59.99.138", - "port": 30013 - }, - { - "ip": "139.59.99.138", - "port": 30015 - }, - { - "ip": "139.59.99.138", - "port": 30017 - }, - { - "ip": "139.59.99.138", - "port": 30018 - }, - { - "ip": "139.59.99.138", - "port": 30020 - }, - { - "ip": "139.59.99.138", - "port": 30021 - }, - { - "ip": "139.59.99.138", - "port": 30022 - }, - { - "ip": "139.59.99.138", - "port": 30023 - }, - { - "ip": "139.59.99.138", - "port": 30025 - }, - { - "ip": "139.59.99.138", - "port": 30027 - }, - { - "ip": "139.59.99.138", - "port": 30028 - }, - { - "ip": "139.59.99.138", - "port": 30029 - }, - { - "ip": "139.59.99.138", - "port": 30031 - }, - { - "ip": "139.59.99.138", - "port": 30034 - }, - { - "ip": "139.59.99.138", - "port": 30035 - }, - { - "ip": "139.59.99.138", - "port": 30037 - }, - { - "ip": "139.59.99.138", - "port": 30038 - }, - { - "ip": "139.59.99.138", - "port": 30040 - }, - { - "ip": "139.59.99.138", - "port": 30043 - }, - { - "ip": "139.59.99.138", - "port": 30044 - }, - { - "ip": "139.59.99.138", - "port": 30047 - }, - { - "ip": "139.59.99.138", - "port": 30050 - }, - { - "ip": "139.59.99.138", - "port": 30052 - }, - { - "ip": "139.59.99.138", - "port": 31006 - }, - { - "ip": "139.59.99.138", - "port": 31010 - }, - { - "ip": "139.59.99.138", - "port": 31012 - }, - { - "ip": "139.59.99.138", - "port": 31015 - }, - { - "ip": "188.166.97.213", - "port": 80 - }, - { - "ip": "188.166.97.213", - "port": 443 - }, - { - "ip": "188.166.97.213", - "port": 1000 - }, - { - "ip": "188.166.97.213", - "port": 1005 - }, - { - "ip": "188.166.97.213", - "port": 1040 - }, - { - "ip": "188.166.97.213", - "port": 1045 - }, - { - "ip": "188.166.97.213", - "port": 1050 - }, - { - "ip": "188.166.97.213", - "port": 9001 - }, - { - "ip": "188.166.97.213", - "port": 49153 - }, - { - "ip": "13.56.176.45", - "port": 80 - }, - { - "ip": "18.218.30.25", - "port": 80 - }, - { - "ip": "34.126.141.53", - "port": 80 - }, - { - "ip": "34.126.141.53", - "port": 443 - }, - { - "ip": "34.126.141.53", - "port": 8090 - }, - { - "ip": "112.160.0.11", - "port": 84 - }, - { - "ip": "112.160.0.11", - "port": 443 - }, - { - "ip": "112.160.0.11", - "port": 8080 - }, - { - "ip": "112.160.0.11", - "port": 9935 - }, - { - "ip": "45.90.218.92", - "port": 80 - }, - { - "ip": "45.90.218.92", - "port": 3101 - }, - { - "ip": "54.144.142.42", - "port": 8080 - }, - { - "ip": "100.24.6.138", - "port": 8080 - }, - { - "ip": "168.138.76.31", - "port": 80 - }, - { - "ip": "168.138.76.31", - "port": 81 - }, - { - "ip": "168.138.76.31", - "port": 82 - }, - { - "ip": "168.138.76.31", - "port": 8081 - }, - { - "ip": "185.239.105.242", - "port": 80 - }, - { - "ip": "185.239.105.242", - "port": 443 - }, - { - "ip": "185.239.105.242", - "port": 9998 - }, - { - "ip": "3.9.61.202", - "port": 80 - }, - { - "ip": "20.198.93.173", - "port": 8080 - }, - { - "ip": "20.198.93.173", - "port": 9080 - }, - { - "ip": "54.74.127.216", - "port": 80 - }, - { - "ip": "54.180.182.230", - "port": 3000 - }, - { - "ip": "54.180.182.230", - "port": 3005 - }, - { - "ip": "54.180.182.230", - "port": 5000 - }, - { - "ip": "54.180.182.230", - "port": 9000 - }, - { - "ip": "54.186.100.251", - "port": 80 - }, - { - "ip": "110.4.41.174", - "port": 80 - }, - { - "ip": "110.4.41.174", - "port": 443 - }, - { - "ip": "110.4.41.174", - "port": 3002 - }, - { - "ip": "110.4.41.174", - "port": 3091 - }, - { - "ip": "110.4.41.174", - "port": 3092 - }, - { - "ip": "110.4.41.174", - "port": 3093 - }, - { - "ip": "110.4.41.174", - "port": 3097 - }, - { - "ip": "110.4.41.174", - "port": 3099 - }, - { - "ip": "110.4.41.174", - "port": 3199 - }, - { - "ip": "110.4.41.174", - "port": 3222 - }, - { - "ip": "110.4.41.174", - "port": 3250 - }, - { - "ip": "110.4.41.174", - "port": 3252 - }, - { - "ip": "110.4.41.174", - "port": 3254 - }, - { - "ip": "110.4.41.174", - "port": 3256 - }, - { - "ip": "110.4.41.174", - "port": 3263 - }, - { - "ip": "110.4.41.174", - "port": 3333 - }, - { - "ip": "110.4.41.174", - "port": 3400 - }, - { - "ip": "110.4.41.174", - "port": 3456 - }, - { - "ip": "110.4.41.174", - "port": 3500 - }, - { - "ip": "110.4.41.174", - "port": 3888 - }, - { - "ip": "110.4.41.174", - "port": 5000 - }, - { - "ip": "110.4.41.174", - "port": 6822 - }, - { - "ip": "110.4.41.174", - "port": 6840 - }, - { - "ip": "110.4.41.174", - "port": 6841 - }, - { - "ip": "110.4.41.174", - "port": 6842 - }, - { - "ip": "110.4.41.174", - "port": 6844 - }, - { - "ip": "110.4.41.174", - "port": 6846 - }, - { - "ip": "110.4.41.174", - "port": 6849 - }, - { - "ip": "110.4.41.174", - "port": 6860 - }, - { - "ip": "110.4.41.174", - "port": 7000 - }, - { - "ip": "110.4.41.174", - "port": 8443 - }, - { - "ip": "110.4.41.174", - "port": 8529 - }, - { - "ip": "110.4.41.174", - "port": 8880 - }, - { - "ip": "34.29.192.98", - "port": 80 - }, - { - "ip": "34.29.192.98", - "port": 3000 - }, - { - "ip": "34.29.192.98", - "port": 3500 - }, - { - "ip": "34.29.192.98", - "port": 4500 - }, - { - "ip": "34.29.192.98", - "port": 5000 - }, - { - "ip": "34.29.192.98", - "port": 6500 - }, - { - "ip": "34.29.192.98", - "port": 9090 - }, - { - "ip": "34.168.6.0", - "port": 5433 - }, - { - "ip": "34.168.6.0", - "port": 5495 - }, - { - "ip": "34.168.6.0", - "port": 5510 - }, - { - "ip": "34.168.6.0", - "port": 5809 - }, - { - "ip": "34.168.6.0", - "port": 5836 - }, - { - "ip": "34.168.6.0", - "port": 5917 - }, - { - "ip": "34.168.6.0", - "port": 5942 - }, - { - "ip": "34.168.6.0", - "port": 6004 - }, - { - "ip": "34.168.6.0", - "port": 6005 - }, - { - "ip": "34.168.6.0", - "port": 6191 - }, - { - "ip": "34.168.6.0", - "port": 6324 - }, - { - "ip": "34.168.6.0", - "port": 6335 - }, - { - "ip": "34.168.6.0", - "port": 6463 - }, - { - "ip": "34.168.6.0", - "port": 6488 - }, - { - "ip": "34.168.6.0", - "port": 6644 - }, - { - "ip": "34.168.6.0", - "port": 6661 - }, - { - "ip": "34.168.6.0", - "port": 6666 - }, - { - "ip": "34.168.6.0", - "port": 6699 - }, - { - "ip": "34.168.6.0", - "port": 6779 - }, - { - "ip": "34.168.6.0", - "port": 6799 - }, - { - "ip": "34.168.6.0", - "port": 6845 - }, - { - "ip": "34.168.6.0", - "port": 6881 - }, - { - "ip": "34.168.6.0", - "port": 6963 - }, - { - "ip": "34.168.6.0", - "port": 6981 - }, - { - "ip": "34.168.6.0", - "port": 7084 - }, - { - "ip": "34.168.6.0", - "port": 7223 - }, - { - "ip": "34.168.6.0", - "port": 7331 - }, - { - "ip": "34.168.6.0", - "port": 7398 - }, - { - "ip": "34.168.6.0", - "port": 7427 - }, - { - "ip": "34.168.6.0", - "port": 7441 - }, - { - "ip": "34.168.6.0", - "port": 7443 - }, - { - "ip": "34.168.6.0", - "port": 7522 - }, - { - "ip": "34.168.6.0", - "port": 7667 - }, - { - "ip": "34.168.6.0", - "port": 7777 - }, - { - "ip": "34.168.6.0", - "port": 7785 - }, - { - "ip": "34.168.6.0", - "port": 7799 - }, - { - "ip": "34.168.6.0", - "port": 7848 - }, - { - "ip": "34.168.6.0", - "port": 7861 - }, - { - "ip": "34.168.6.0", - "port": 8013 - }, - { - "ip": "34.168.6.0", - "port": 8020 - }, - { - "ip": "34.168.6.0", - "port": 8042 - }, - { - "ip": "34.168.6.0", - "port": 8051 - }, - { - "ip": "34.168.6.0", - "port": 8056 - }, - { - "ip": "34.168.6.0", - "port": 8059 - }, - { - "ip": "147.182.185.61", - "port": 80 - }, - { - "ip": "147.182.185.61", - "port": 443 - }, - { - "ip": "147.182.185.61", - "port": 8080 - }, - { - "ip": "165.227.243.41", - "port": 80 - }, - { - "ip": "165.227.243.41", - "port": 443 - }, - { - "ip": "165.227.243.41", - "port": 9320 - }, - { - "ip": "34.127.33.229", - "port": 5444 - }, - { - "ip": "34.127.33.229", - "port": 5455 - }, - { - "ip": "34.127.33.229", - "port": 5595 - }, - { - "ip": "34.127.33.229", - "port": 5606 - }, - { - "ip": "34.127.33.229", - "port": 5678 - }, - { - "ip": "34.127.33.229", - "port": 5896 - }, - { - "ip": "34.127.33.229", - "port": 5913 - }, - { - "ip": "34.127.33.229", - "port": 5919 - }, - { - "ip": "34.127.33.229", - "port": 5925 - }, - { - "ip": "34.127.33.229", - "port": 5983 - }, - { - "ip": "34.127.33.229", - "port": 5990 - }, - { - "ip": "34.127.33.229", - "port": 6004 - }, - { - "ip": "34.127.33.229", - "port": 6010 - }, - { - "ip": "34.127.33.229", - "port": 6011 - }, - { - "ip": "34.127.33.229", - "port": 6020 - }, - { - "ip": "34.127.33.229", - "port": 6203 - }, - { - "ip": "34.127.33.229", - "port": 6220 - }, - { - "ip": "34.127.33.229", - "port": 6368 - }, - { - "ip": "34.127.33.229", - "port": 6378 - }, - { - "ip": "34.127.33.229", - "port": 6390 - }, - { - "ip": "34.127.33.229", - "port": 6484 - }, - { - "ip": "34.127.33.229", - "port": 6503 - }, - { - "ip": "34.127.33.229", - "port": 6521 - }, - { - "ip": "34.127.33.229", - "port": 6601 - }, - { - "ip": "34.127.33.229", - "port": 6666 - }, - { - "ip": "34.127.33.229", - "port": 6674 - }, - { - "ip": "34.127.33.229", - "port": 6770 - }, - { - "ip": "34.127.33.229", - "port": 6776 - }, - { - "ip": "34.127.33.229", - "port": 7002 - }, - { - "ip": "34.127.33.229", - "port": 7010 - }, - { - "ip": "34.127.33.229", - "port": 7046 - }, - { - "ip": "34.127.33.229", - "port": 7139 - }, - { - "ip": "34.127.33.229", - "port": 7306 - }, - { - "ip": "34.127.33.229", - "port": 7522 - }, - { - "ip": "34.127.33.229", - "port": 7570 - }, - { - "ip": "34.127.33.229", - "port": 7651 - }, - { - "ip": "34.127.33.229", - "port": 7779 - }, - { - "ip": "34.127.33.229", - "port": 7896 - }, - { - "ip": "34.127.33.229", - "port": 7928 - }, - { - "ip": "34.127.33.229", - "port": 8017 - }, - { - "ip": "34.127.33.229", - "port": 8020 - }, - { - "ip": "34.127.33.229", - "port": 8022 - }, - { - "ip": "34.127.33.229", - "port": 8046 - }, - { - "ip": "34.127.33.229", - "port": 8048 - }, - { - "ip": "34.127.33.229", - "port": 8074 - }, - { - "ip": "34.127.33.229", - "port": 8077 - }, - { - "ip": "34.168.161.245", - "port": 5599 - }, - { - "ip": "34.168.161.245", - "port": 5607 - }, - { - "ip": "34.168.161.245", - "port": 5609 - }, - { - "ip": "34.168.161.245", - "port": 5721 - }, - { - "ip": "34.168.161.245", - "port": 5856 - }, - { - "ip": "34.168.161.245", - "port": 5900 - }, - { - "ip": "34.168.161.245", - "port": 5903 - }, - { - "ip": "34.168.161.245", - "port": 5906 - }, - { - "ip": "34.168.161.245", - "port": 5911 - }, - { - "ip": "34.168.161.245", - "port": 5921 - }, - { - "ip": "34.168.161.245", - "port": 5965 - }, - { - "ip": "34.168.161.245", - "port": 5983 - }, - { - "ip": "34.168.161.245", - "port": 5993 - }, - { - "ip": "34.168.161.245", - "port": 6009 - }, - { - "ip": "34.168.161.245", - "port": 6061 - }, - { - "ip": "34.168.161.245", - "port": 6066 - }, - { - "ip": "34.168.161.245", - "port": 6097 - }, - { - "ip": "34.168.161.245", - "port": 6160 - }, - { - "ip": "34.168.161.245", - "port": 6379 - }, - { - "ip": "34.168.161.245", - "port": 6500 - }, - { - "ip": "34.168.161.245", - "port": 6565 - }, - { - "ip": "34.168.161.245", - "port": 6605 - }, - { - "ip": "34.168.161.245", - "port": 6766 - }, - { - "ip": "34.168.161.245", - "port": 6799 - }, - { - "ip": "34.168.161.245", - "port": 6840 - }, - { - "ip": "34.168.161.245", - "port": 6867 - }, - { - "ip": "34.168.161.245", - "port": 7003 - }, - { - "ip": "34.168.161.245", - "port": 7011 - }, - { - "ip": "34.168.161.245", - "port": 7018 - }, - { - "ip": "34.168.161.245", - "port": 7057 - }, - { - "ip": "34.168.161.245", - "port": 7086 - }, - { - "ip": "34.168.161.245", - "port": 7126 - }, - { - "ip": "34.168.161.245", - "port": 7131 - }, - { - "ip": "34.168.161.245", - "port": 7162 - }, - { - "ip": "34.168.161.245", - "port": 7169 - }, - { - "ip": "34.168.161.245", - "port": 7207 - }, - { - "ip": "34.168.161.245", - "port": 7246 - }, - { - "ip": "34.168.161.245", - "port": 7301 - }, - { - "ip": "34.168.161.245", - "port": 7302 - }, - { - "ip": "34.168.161.245", - "port": 7433 - }, - { - "ip": "34.168.161.245", - "port": 7537 - }, - { - "ip": "34.168.161.245", - "port": 7567 - }, - { - "ip": "34.168.161.245", - "port": 7717 - }, - { - "ip": "34.168.161.245", - "port": 7742 - }, - { - "ip": "34.168.161.245", - "port": 7794 - }, - { - "ip": "34.168.161.245", - "port": 7822 - }, - { - "ip": "34.168.161.245", - "port": 7873 - }, - { - "ip": "34.168.161.245", - "port": 7931 - }, - { - "ip": "34.168.161.245", - "port": 7965 - }, - { - "ip": "34.168.161.245", - "port": 8001 - }, - { - "ip": "34.168.161.245", - "port": 8019 - }, - { - "ip": "34.168.161.245", - "port": 8032 - }, - { - "ip": "34.168.161.245", - "port": 8062 - }, - { - "ip": "34.168.161.245", - "port": 8077 - }, - { - "ip": "78.47.230.107", - "port": 80 - }, - { - "ip": "134.102.219.4", - "port": 80 - }, - { - "ip": "134.102.219.4", - "port": 443 - }, - { - "ip": "134.102.219.4", - "port": 8001 - }, - { - "ip": "134.102.219.4", - "port": 8002 - }, - { - "ip": "134.102.219.4", - "port": 9090 - }, - { - "ip": "134.102.219.4", - "port": 17125 - }, - { - "ip": "171.22.24.209", - "port": 80 - }, - { - "ip": "171.22.24.209", - "port": 443 - }, - { - "ip": "171.22.24.209", - "port": 8080 - }, - { - "ip": "202.182.112.29", - "port": 80 - }, - { - "ip": "202.182.112.29", - "port": 443 - }, - { - "ip": "202.182.112.29", - "port": 888 - }, - { - "ip": "202.182.112.29", - "port": 3000 - }, - { - "ip": "202.182.112.29", - "port": 8000 - }, - { - "ip": "202.182.112.29", - "port": 8080 - }, - { - "ip": "217.182.171.139", - "port": 80 - }, - { - "ip": "217.182.171.139", - "port": 443 - }, - { - "ip": "217.182.171.139", - "port": 3000 - }, - { - "ip": "217.182.171.139", - "port": 3443 - }, - { - "ip": "217.182.171.139", - "port": 4001 - }, - { - "ip": "217.182.171.139", - "port": 5000 - }, - { - "ip": "217.182.171.139", - "port": 8080 - }, - { - "ip": "217.182.171.139", - "port": 8081 - }, - { - "ip": "3.232.116.173", - "port": 80 - }, - { - "ip": "34.82.24.106", - "port": 5445 - }, - { - "ip": "34.82.24.106", - "port": 5494 - }, - { - "ip": "34.82.24.106", - "port": 5543 - }, - { - "ip": "34.82.24.106", - "port": 5551 - }, - { - "ip": "34.82.24.106", - "port": 5557 - }, - { - "ip": "34.82.24.106", - "port": 5595 - }, - { - "ip": "34.82.24.106", - "port": 5613 - }, - { - "ip": "34.82.24.106", - "port": 5671 - }, - { - "ip": "34.82.24.106", - "port": 5673 - }, - { - "ip": "34.82.24.106", - "port": 5812 - }, - { - "ip": "34.82.24.106", - "port": 5843 - }, - { - "ip": "34.82.24.106", - "port": 5880 - }, - { - "ip": "34.82.24.106", - "port": 5889 - }, - { - "ip": "34.82.24.106", - "port": 5991 - }, - { - "ip": "34.82.24.106", - "port": 6002 - }, - { - "ip": "34.82.24.106", - "port": 6142 - }, - { - "ip": "34.82.24.106", - "port": 6195 - }, - { - "ip": "34.82.24.106", - "port": 6488 - }, - { - "ip": "34.82.24.106", - "port": 6544 - }, - { - "ip": "34.82.24.106", - "port": 6671 - }, - { - "ip": "34.82.24.106", - "port": 6699 - }, - { - "ip": "34.82.24.106", - "port": 6788 - }, - { - "ip": "34.82.24.106", - "port": 6830 - }, - { - "ip": "34.82.24.106", - "port": 6985 - }, - { - "ip": "34.82.24.106", - "port": 7000 - }, - { - "ip": "34.82.24.106", - "port": 7007 - }, - { - "ip": "34.82.24.106", - "port": 7071 - }, - { - "ip": "34.82.24.106", - "port": 7080 - }, - { - "ip": "34.82.24.106", - "port": 7100 - }, - { - "ip": "34.82.24.106", - "port": 7174 - }, - { - "ip": "34.82.24.106", - "port": 7200 - }, - { - "ip": "34.82.24.106", - "port": 7262 - }, - { - "ip": "34.82.24.106", - "port": 7275 - }, - { - "ip": "34.82.24.106", - "port": 7311 - }, - { - "ip": "34.82.24.106", - "port": 7457 - }, - { - "ip": "34.82.24.106", - "port": 7537 - }, - { - "ip": "34.82.24.106", - "port": 7673 - }, - { - "ip": "34.82.24.106", - "port": 7677 - }, - { - "ip": "34.82.24.106", - "port": 7766 - }, - { - "ip": "34.82.24.106", - "port": 7788 - }, - { - "ip": "34.82.24.106", - "port": 7793 - }, - { - "ip": "34.82.24.106", - "port": 7796 - }, - { - "ip": "34.82.24.106", - "port": 7805 - }, - { - "ip": "34.82.24.106", - "port": 8000 - }, - { - "ip": "34.82.24.106", - "port": 8006 - }, - { - "ip": "34.82.24.106", - "port": 8016 - }, - { - "ip": "34.82.24.106", - "port": 8017 - }, - { - "ip": "34.82.24.106", - "port": 8038 - }, - { - "ip": "34.82.24.106", - "port": 8066 - }, - { - "ip": "34.82.24.106", - "port": 8072 - }, - { - "ip": "34.82.24.106", - "port": 8073 - }, - { - "ip": "34.123.37.24", - "port": 8080 - }, - { - "ip": "159.223.165.183", - "port": 80 - }, - { - "ip": "159.223.165.183", - "port": 443 - }, - { - "ip": "159.223.165.183", - "port": 8080 - }, - { - "ip": "159.223.165.183", - "port": 8081 - }, - { - "ip": "159.223.165.183", - "port": 8101 - }, - { - "ip": "211.238.101.178", - "port": 80 - }, - { - "ip": "211.238.101.178", - "port": 84 - }, - { - "ip": "211.238.101.178", - "port": 443 - }, - { - "ip": "211.238.101.178", - "port": 8080 - }, - { - "ip": "115.22.77.208", - "port": 80 - }, - { - "ip": "115.22.77.208", - "port": 84 - }, - { - "ip": "115.22.77.208", - "port": 8080 - }, - { - "ip": "115.22.77.208", - "port": 9935 - }, - { - "ip": "172.245.225.234", - "port": 8080 - }, - { - "ip": "185.162.250.214", - "port": 80 - }, - { - "ip": "185.162.250.214", - "port": 8045 - }, - { - "ip": "185.162.250.214", - "port": 8081 - }, - { - "ip": "213.59.118.171", - "port": 80 - }, - { - "ip": "213.59.118.171", - "port": 8080 - }, - { - "ip": "213.59.118.171", - "port": 8888 - }, - { - "ip": "1.209.233.202", - "port": 80 - }, - { - "ip": "1.209.233.202", - "port": 8080 - }, - { - "ip": "1.209.233.202", - "port": 9935 - }, - { - "ip": "46.101.41.69", - "port": 80 - }, - { - "ip": "46.101.41.69", - "port": 3000 - }, - { - "ip": "46.101.41.69", - "port": 3002 - }, - { - "ip": "47.104.190.202", - "port": 80 - }, - { - "ip": "47.104.190.202", - "port": 443 - }, - { - "ip": "47.104.190.202", - "port": 8080 - }, - { - "ip": "47.104.190.202", - "port": 8092 - }, - { - "ip": "112.216.156.170", - "port": 80 - }, - { - "ip": "112.216.156.170", - "port": 81 - }, - { - "ip": "112.216.156.170", - "port": 84 - }, - { - "ip": "112.216.156.170", - "port": 443 - }, - { - "ip": "112.216.156.170", - "port": 8080 - }, - { - "ip": "112.216.156.170", - "port": 9935 - }, - { - "ip": "162.241.129.193", - "port": 80 - }, - { - "ip": "162.241.129.193", - "port": 443 - }, - { - "ip": "162.241.129.193", - "port": 2082 - }, - { - "ip": "162.241.129.193", - "port": 2083 - }, - { - "ip": "162.241.129.193", - "port": 2086 - }, - { - "ip": "162.241.129.193", - "port": 2087 - }, - { - "ip": "162.241.129.193", - "port": 2095 - }, - { - "ip": "162.241.129.193", - "port": 2096 - }, - { - "ip": "162.241.129.193", - "port": 3000 - }, - { - "ip": "162.241.129.193", - "port": 3001 - }, - { - "ip": "162.241.129.193", - "port": 3002 - }, - { - "ip": "162.241.129.193", - "port": 3003 - }, - { - "ip": "162.241.129.193", - "port": 3004 - }, - { - "ip": "162.241.129.193", - "port": 3005 - }, - { - "ip": "162.241.129.193", - "port": 3006 - }, - { - "ip": "162.241.129.193", - "port": 3007 - }, - { - "ip": "162.241.129.193", - "port": 3008 - }, - { - "ip": "162.241.129.193", - "port": 3333 - }, - { - "ip": "177.25.63.58", - "port": 80 - }, - { - "ip": "177.25.63.58", - "port": 443 - }, - { - "ip": "177.25.63.58", - "port": 7070 - }, - { - "ip": "177.25.63.58", - "port": 8601 - }, - { - "ip": "177.25.63.58", - "port": 8800 - }, - { - "ip": "177.25.63.58", - "port": 9100 - }, - { - "ip": "177.25.63.58", - "port": 9595 - }, - { - "ip": "177.25.63.58", - "port": 9999 - }, - { - "ip": "177.25.63.58", - "port": 31718 - }, - { - "ip": "177.25.63.58", - "port": 31783 - }, - { - "ip": "198.181.42.141", - "port": 80 - }, - { - "ip": "198.181.42.141", - "port": 443 - }, - { - "ip": "198.181.42.141", - "port": 6443 - }, - { - "ip": "198.181.42.141", - "port": 7001 - }, - { - "ip": "198.181.42.141", - "port": 7010 - }, - { - "ip": "198.181.42.141", - "port": 7080 - }, - { - "ip": "198.181.42.141", - "port": 7380 - }, - { - "ip": "198.181.42.141", - "port": 7417 - }, - { - "ip": "198.181.42.141", - "port": 7443 - }, - { - "ip": "198.181.42.141", - "port": 8080 - }, - { - "ip": "198.181.42.141", - "port": 8443 - }, - { - "ip": "198.181.42.141", - "port": 9080 - }, - { - "ip": "198.181.42.141", - "port": 9443 - }, - { - "ip": "198.181.42.141", - "port": 9888 - }, - { - "ip": "3.7.147.32", - "port": 80 - }, - { - "ip": "13.39.164.143", - "port": 80 - }, - { - "ip": "34.226.232.183", - "port": 80 - }, - { - "ip": "34.226.232.183", - "port": 443 - }, - { - "ip": "34.226.232.183", - "port": 5000 - }, - { - "ip": "34.226.232.183", - "port": 8080 - }, - { - "ip": "34.226.232.183", - "port": 8082 - }, - { - "ip": "34.226.232.183", - "port": 8090 - }, - { - "ip": "34.226.232.183", - "port": 8443 - }, - { - "ip": "51.81.187.199", - "port": 80 - }, - { - "ip": "51.81.187.199", - "port": 443 - }, - { - "ip": "51.81.187.199", - "port": 8080 - }, - { - "ip": "104.248.100.150", - "port": 8080 - }, - { - "ip": "122.54.18.231", - "port": 80 - }, - { - "ip": "122.54.18.231", - "port": 5000 - }, - { - "ip": "3.19.198.81", - "port": 80 - }, - { - "ip": "3.19.198.81", - "port": 8080 - }, - { - "ip": "14.33.192.150", - "port": 80 - }, - { - "ip": "14.33.192.150", - "port": 81 - }, - { - "ip": "14.33.192.150", - "port": 84 - }, - { - "ip": "14.33.192.150", - "port": 443 - }, - { - "ip": "14.33.192.150", - "port": 8080 - }, - { - "ip": "14.33.192.150", - "port": 9935 - }, - { - "ip": "52.56.156.85", - "port": 80 - }, - { - "ip": "52.56.156.85", - "port": 443 - }, - { - "ip": "52.56.156.85", - "port": 8080 - }, - { - "ip": "52.56.156.85", - "port": 8081 - }, - { - "ip": "52.56.156.85", - "port": 8082 - }, - { - "ip": "52.56.156.85", - "port": 8084 - }, - { - "ip": "52.56.156.85", - "port": 8087 - }, - { - "ip": "52.56.156.85", - "port": 8090 - }, - { - "ip": "52.56.156.85", - "port": 8172 - }, - { - "ip": "54.39.99.220", - "port": 80 - }, - { - "ip": "54.39.99.220", - "port": 443 - }, - { - "ip": "54.39.99.220", - "port": 3000 - }, - { - "ip": "54.39.99.220", - "port": 8080 - }, - { - "ip": "61.77.106.112", - "port": 80 - }, - { - "ip": "61.77.106.112", - "port": 84 - }, - { - "ip": "61.77.106.112", - "port": 443 - }, - { - "ip": "61.77.106.112", - "port": 8080 - }, - { - "ip": "61.77.106.112", - "port": 9935 - }, - { - "ip": "66.94.109.62", - "port": 80 - }, - { - "ip": "66.94.109.62", - "port": 443 - }, - { - "ip": "66.94.109.62", - "port": 3000 - }, - { - "ip": "66.94.109.62", - "port": 5000 - }, - { - "ip": "66.94.109.62", - "port": 8000 - }, - { - "ip": "66.94.109.62", - "port": 8002 - }, - { - "ip": "66.94.109.62", - "port": 8080 - }, - { - "ip": "68.178.161.9", - "port": 80 - }, - { - "ip": "68.178.161.9", - "port": 443 - }, - { - "ip": "68.178.161.9", - "port": 6001 - }, - { - "ip": "68.178.161.9", - "port": 6010 - }, - { - "ip": "5.161.134.232", - "port": 80 - }, - { - "ip": "5.161.134.232", - "port": 443 - }, - { - "ip": "5.161.134.232", - "port": 3060 - }, - { - "ip": "5.161.134.232", - "port": 4001 - }, - { - "ip": "5.161.134.232", - "port": 4100 - }, - { - "ip": "13.36.116.129", - "port": 8080 - }, - { - "ip": "45.251.112.69", - "port": 80 - }, - { - "ip": "45.251.112.69", - "port": 81 - }, - { - "ip": "45.251.112.69", - "port": 1001 - }, - { - "ip": "45.251.112.69", - "port": 1204 - }, - { - "ip": "45.251.112.69", - "port": 1211 - }, - { - "ip": "45.251.112.69", - "port": 2004 - }, - { - "ip": "45.251.112.69", - "port": 2404 - }, - { - "ip": "45.251.112.69", - "port": 3017 - }, - { - "ip": "45.251.112.69", - "port": 5000 - }, - { - "ip": "45.251.112.69", - "port": 5002 - }, - { - "ip": "45.251.112.69", - "port": 5004 - }, - { - "ip": "45.251.112.69", - "port": 6002 - }, - { - "ip": "45.251.112.69", - "port": 6006 - }, - { - "ip": "45.251.112.69", - "port": 6011 - }, - { - "ip": "45.251.112.69", - "port": 6025 - }, - { - "ip": "45.251.112.69", - "port": 8081 - }, - { - "ip": "45.251.112.69", - "port": 8082 - }, - { - "ip": "45.251.112.69", - "port": 8083 - }, - { - "ip": "45.251.112.69", - "port": 8085 - }, - { - "ip": "45.251.112.69", - "port": 8086 - }, - { - "ip": "45.251.112.69", - "port": 8087 - }, - { - "ip": "45.251.112.69", - "port": 8088 - }, - { - "ip": "45.251.112.69", - "port": 8881 - }, - { - "ip": "45.251.112.69", - "port": 8894 - }, - { - "ip": "45.251.112.69", - "port": 9002 - }, - { - "ip": "45.251.112.69", - "port": 9006 - }, - { - "ip": "45.251.112.69", - "port": 9011 - }, - { - "ip": "45.251.112.69", - "port": 9018 - }, - { - "ip": "45.251.112.69", - "port": 9021 - }, - { - "ip": "45.251.112.69", - "port": 9022 - }, - { - "ip": "45.251.112.69", - "port": 9024 - }, - { - "ip": "45.251.112.69", - "port": 9025 - }, - { - "ip": "64.227.129.186", - "port": 80 - }, - { - "ip": "64.227.129.186", - "port": 443 - }, - { - "ip": "64.227.129.186", - "port": 5005 - }, - { - "ip": "64.227.129.186", - "port": 8002 - }, - { - "ip": "64.227.129.186", - "port": 8084 - }, - { - "ip": "64.227.129.186", - "port": 8581 - }, - { - "ip": "64.227.129.186", - "port": 9098 - }, - { - "ip": "188.166.246.232", - "port": 80 - }, - { - "ip": "188.166.246.232", - "port": 443 - }, - { - "ip": "188.166.246.232", - "port": 8080 - }, - { - "ip": "3.67.91.63", - "port": 80 - }, - { - "ip": "3.67.91.63", - "port": 443 - }, - { - "ip": "3.67.91.63", - "port": 3001 - }, - { - "ip": "3.67.91.63", - "port": 3002 - }, - { - "ip": "3.67.91.63", - "port": 3008 - }, - { - "ip": "3.67.91.63", - "port": 3010 - }, - { - "ip": "3.67.91.63", - "port": 3011 - }, - { - "ip": "3.67.91.63", - "port": 3101 - }, - { - "ip": "3.67.91.63", - "port": 3102 - }, - { - "ip": "3.67.91.63", - "port": 8080 - }, - { - "ip": "3.130.197.75", - "port": 80 - }, - { - "ip": "34.132.185.231", - "port": 2020 - }, - { - "ip": "34.132.185.231", - "port": 2021 - }, - { - "ip": "34.132.185.231", - "port": 9091 - }, - { - "ip": "34.132.185.231", - "port": 10250 - }, - { - "ip": "34.132.185.231", - "port": 10255 - }, - { - "ip": "34.132.185.231", - "port": 10256 - }, - { - "ip": "34.132.185.231", - "port": 30050 - }, - { - "ip": "34.132.185.231", - "port": 30076 - }, - { - "ip": "34.132.185.231", - "port": 30111 - }, - { - "ip": "34.132.185.231", - "port": 30120 - }, - { - "ip": "34.132.185.231", - "port": 30444 - }, - { - "ip": "34.132.185.231", - "port": 30473 - }, - { - "ip": "34.132.185.231", - "port": 30478 - }, - { - "ip": "34.132.185.231", - "port": 30588 - }, - { - "ip": "34.132.185.231", - "port": 30684 - }, - { - "ip": "34.132.185.231", - "port": 30700 - }, - { - "ip": "34.132.185.231", - "port": 30729 - }, - { - "ip": "34.132.185.231", - "port": 30855 - }, - { - "ip": "34.132.185.231", - "port": 30999 - }, - { - "ip": "34.132.185.231", - "port": 31017 - }, - { - "ip": "34.132.185.231", - "port": 31270 - }, - { - "ip": "34.132.185.231", - "port": 31557 - }, - { - "ip": "34.132.185.231", - "port": 31618 - }, - { - "ip": "34.132.185.231", - "port": 31872 - }, - { - "ip": "34.132.185.231", - "port": 31956 - }, - { - "ip": "34.132.185.231", - "port": 32022 - }, - { - "ip": "34.132.185.231", - "port": 32036 - }, - { - "ip": "34.132.185.231", - "port": 32053 - }, - { - "ip": "34.132.185.231", - "port": 32173 - }, - { - "ip": "34.132.185.231", - "port": 32220 - }, - { - "ip": "34.132.185.231", - "port": 32380 - }, - { - "ip": "34.132.185.231", - "port": 32382 - }, - { - "ip": "34.132.185.231", - "port": 32607 - }, - { - "ip": "34.132.185.231", - "port": 32738 - }, - { - "ip": "46.36.218.98", - "port": 80 - }, - { - "ip": "46.36.218.98", - "port": 443 - }, - { - "ip": "46.36.218.98", - "port": 1337 - }, - { - "ip": "46.36.218.98", - "port": 3001 - }, - { - "ip": "46.36.218.98", - "port": 4000 - }, - { - "ip": "46.36.218.98", - "port": 5001 - }, - { - "ip": "46.36.218.98", - "port": 7777 - }, - { - "ip": "46.36.218.98", - "port": 8888 - }, - { - "ip": "144.217.7.222", - "port": 80 - }, - { - "ip": "144.217.7.222", - "port": 443 - }, - { - "ip": "144.217.7.222", - "port": 3000 - }, - { - "ip": "144.217.7.222", - "port": 3001 - }, - { - "ip": "144.217.7.222", - "port": 3002 - }, - { - "ip": "144.217.7.222", - "port": 3017 - }, - { - "ip": "144.217.7.222", - "port": 4000 - }, - { - "ip": "144.217.7.222", - "port": 8080 - }, - { - "ip": "144.217.7.222", - "port": 8083 - }, - { - "ip": "144.217.7.222", - "port": 8443 - }, - { - "ip": "210.183.74.35", - "port": 80 - }, - { - "ip": "210.183.74.35", - "port": 84 - }, - { - "ip": "210.183.74.35", - "port": 443 - }, - { - "ip": "210.183.74.35", - "port": 8080 - }, - { - "ip": "210.183.74.35", - "port": 9935 - }, - { - "ip": "57.128.49.153", - "port": 80 - }, - { - "ip": "57.128.49.153", - "port": 443 - }, - { - "ip": "57.128.49.153", - "port": 3000 - }, - { - "ip": "57.128.49.153", - "port": 4000 - }, - { - "ip": "57.128.49.153", - "port": 4500 - }, - { - "ip": "57.128.49.153", - "port": 8080 - }, - { - "ip": "59.16.162.13", - "port": 80 - }, - { - "ip": "59.16.162.13", - "port": 84 - }, - { - "ip": "59.16.162.13", - "port": 443 - }, - { - "ip": "59.16.162.13", - "port": 8080 - }, - { - "ip": "59.16.162.13", - "port": 9935 - }, - { - "ip": "62.109.13.138", - "port": 80 - }, - { - "ip": "62.109.13.138", - "port": 3000 - }, - { - "ip": "62.109.13.138", - "port": 4444 - }, - { - "ip": "62.109.13.138", - "port": 8888 - }, - { - "ip": "112.220.124.106", - "port": 80 - }, - { - "ip": "112.220.124.106", - "port": 84 - }, - { - "ip": "112.220.124.106", - "port": 8080 - }, - { - "ip": "112.220.124.106", - "port": 9935 - }, - { - "ip": "161.35.57.151", - "port": 80 - }, - { - "ip": "161.35.57.151", - "port": 443 - }, - { - "ip": "161.35.57.151", - "port": 3000 - }, - { - "ip": "161.35.57.151", - "port": 3033 - }, - { - "ip": "161.35.57.151", - "port": 3333 - }, - { - "ip": "161.35.57.151", - "port": 5555 - }, - { - "ip": "161.35.57.151", - "port": 8000 - }, - { - "ip": "161.35.57.151", - "port": 8080 - }, - { - "ip": "161.35.57.151", - "port": 9000 - }, - { - "ip": "161.35.57.151", - "port": 9080 - }, - { - "ip": "35.247.196.88", - "port": 80 - }, - { - "ip": "35.247.196.88", - "port": 8080 - }, - { - "ip": "35.247.196.88", - "port": 8081 - }, - { - "ip": "92.154.57.226", - "port": 80 - }, - { - "ip": "92.154.57.226", - "port": 443 - }, - { - "ip": "92.154.57.226", - "port": 3000 - }, - { - "ip": "92.154.57.226", - "port": 8080 - }, - { - "ip": "149.28.153.226", - "port": 80 - }, - { - "ip": "149.28.153.226", - "port": 81 - }, - { - "ip": "149.28.153.226", - "port": 3000 - }, - { - "ip": "149.28.153.226", - "port": 8001 - }, - { - "ip": "149.28.153.226", - "port": 8003 - }, - { - "ip": "149.28.153.226", - "port": 8010 - }, - { - "ip": "149.28.153.226", - "port": 8011 - }, - { - "ip": "149.28.153.226", - "port": 8012 - }, - { - "ip": "149.28.153.226", - "port": 8080 - }, - { - "ip": "149.28.153.226", - "port": 8083 - }, - { - "ip": "195.137.166.212", - "port": 80 - }, - { - "ip": "195.137.166.212", - "port": 5357 - }, - { - "ip": "195.137.166.212", - "port": 5985 - }, - { - "ip": "195.137.166.212", - "port": 8172 - }, - { - "ip": "195.137.166.212", - "port": 44320 - }, - { - "ip": "195.137.166.212", - "port": 44321 - }, - { - "ip": "195.137.166.212", - "port": 44420 - }, - { - "ip": "195.137.166.212", - "port": 56145 - }, - { - "ip": "195.137.166.212", - "port": 61200 - }, - { - "ip": "195.137.166.212", - "port": 61203 - }, - { - "ip": "195.137.166.212", - "port": 62699 - }, - { - "ip": "1.224.146.199", - "port": 80 - }, - { - "ip": "1.224.146.199", - "port": 443 - }, - { - "ip": "1.224.146.199", - "port": 2210 - }, - { - "ip": "1.224.146.199", - "port": 5000 - }, - { - "ip": "1.224.146.199", - "port": 5001 - }, - { - "ip": "54.176.163.67", - "port": 80 - }, - { - "ip": "161.156.161.8", - "port": 80 - }, - { - "ip": "161.156.161.8", - "port": 8081 - }, - { - "ip": "161.156.161.8", - "port": 8082 - }, - { - "ip": "161.156.161.8", - "port": 8085 - }, - { - "ip": "161.156.161.8", - "port": 8989 - }, - { - "ip": "168.138.201.144", - "port": 8080 - }, - { - "ip": "206.189.0.55", - "port": 80 - }, - { - "ip": "206.189.0.55", - "port": 443 - }, - { - "ip": "206.189.0.55", - "port": 3838 - }, - { - "ip": "34.31.40.122", - "port": 80 - }, - { - "ip": "34.31.40.122", - "port": 8080 - }, - { - "ip": "34.31.40.122", - "port": 8081 - }, - { - "ip": "37.205.8.210", - "port": 80 - }, - { - "ip": "37.205.8.210", - "port": 443 - }, - { - "ip": "37.205.8.210", - "port": 56176 - }, - { - "ip": "47.100.122.35", - "port": 80 - }, - { - "ip": "47.100.122.35", - "port": 8182 - }, - { - "ip": "118.38.197.122", - "port": 80 - }, - { - "ip": "118.38.197.122", - "port": 84 - }, - { - "ip": "118.38.197.122", - "port": 8080 - }, - { - "ip": "118.38.197.122", - "port": 9935 - }, - { - "ip": "129.148.46.63", - "port": 80 - }, - { - "ip": "5.161.132.56", - "port": 80 - }, - { - "ip": "5.161.132.56", - "port": 5000 - }, - { - "ip": "35.198.13.98", - "port": 80 - }, - { - "ip": "35.198.13.98", - "port": 8080 - }, - { - "ip": "35.198.13.98", - "port": 8081 - }, - { - "ip": "147.182.130.180", - "port": 8080 - }, - { - "ip": "161.97.117.64", - "port": 80 - }, - { - "ip": "161.97.117.64", - "port": 443 - }, - { - "ip": "161.97.117.64", - "port": 5500 - }, - { - "ip": "161.97.117.64", - "port": 8000 - }, - { - "ip": "161.97.117.64", - "port": 8090 - }, - { - "ip": "161.97.117.64", - "port": 8701 - }, - { - "ip": "167.114.208.155", - "port": 80 - }, - { - "ip": "167.114.208.155", - "port": 81 - }, - { - "ip": "167.114.208.155", - "port": 443 - }, - { - "ip": "167.114.208.155", - "port": 444 - }, - { - "ip": "167.114.208.155", - "port": 2077 - }, - { - "ip": "167.114.208.155", - "port": 2078 - }, - { - "ip": "167.114.208.155", - "port": 2082 - }, - { - "ip": "167.114.208.155", - "port": 2083 - }, - { - "ip": "167.114.208.155", - "port": 2086 - }, - { - "ip": "167.114.208.155", - "port": 2087 - }, - { - "ip": "167.114.208.155", - "port": 2091 - }, - { - "ip": "167.114.208.155", - "port": 2095 - }, - { - "ip": "167.114.208.155", - "port": 2096 - }, - { - "ip": "167.114.208.155", - "port": 8082 - }, - { - "ip": "51.38.157.3", - "port": 443 - }, - { - "ip": "51.38.157.3", - "port": 3001 - }, - { - "ip": "51.38.157.3", - "port": 3002 - }, - { - "ip": "51.38.157.3", - "port": 3003 - }, - { - "ip": "52.42.3.32", - "port": 5000 - }, - { - "ip": "54.152.139.39", - "port": 80 - }, - { - "ip": "54.152.139.39", - "port": 443 - }, - { - "ip": "54.152.139.39", - "port": 1983 - }, - { - "ip": "54.152.139.39", - "port": 8084 - }, - { - "ip": "61.133.215.157", - "port": 8090 - }, - { - "ip": "61.133.215.157", - "port": 10000 - }, - { - "ip": "81.68.213.63", - "port": 8843 - }, - { - "ip": "81.68.213.63", - "port": 9099 - }, - { - "ip": "81.68.213.63", - "port": 9100 - }, - { - "ip": "81.68.213.63", - "port": 9200 - }, - { - "ip": "119.199.215.171", - "port": 84 - }, - { - "ip": "119.199.215.171", - "port": 88 - }, - { - "ip": "119.199.215.171", - "port": 8080 - }, - { - "ip": "185.209.163.8", - "port": 5000 - }, - { - "ip": "185.209.163.8", - "port": 7000 - }, - { - "ip": "185.209.163.8", - "port": 8080 - }, - { - "ip": "185.209.163.8", - "port": 8083 - }, - { - "ip": "185.209.163.8", - "port": 9100 - }, - { - "ip": "185.209.163.8", - "port": 25080 - }, - { - "ip": "210.126.122.202", - "port": 80 - }, - { - "ip": "210.126.122.202", - "port": 84 - }, - { - "ip": "210.126.122.202", - "port": 8080 - }, - { - "ip": "210.126.122.202", - "port": 9935 - }, - { - "ip": "34.253.181.155", - "port": 8085 - }, - { - "ip": "35.198.1.111", - "port": 80 - }, - { - "ip": "35.198.1.111", - "port": 8080 - }, - { - "ip": "35.198.1.111", - "port": 8081 - }, - { - "ip": "52.18.212.74", - "port": 80 - }, - { - "ip": "52.18.212.74", - "port": 443 - }, - { - "ip": "52.18.212.74", - "port": 8080 - }, - { - "ip": "82.146.58.220", - "port": 80 - }, - { - "ip": "82.146.58.220", - "port": 443 - }, - { - "ip": "103.124.100.186", - "port": 80 - }, - { - "ip": "103.124.100.186", - "port": 443 - }, - { - "ip": "103.124.100.186", - "port": 8000 - }, - { - "ip": "103.124.100.186", - "port": 8080 - }, - { - "ip": "119.193.65.179", - "port": 80 - }, - { - "ip": "119.193.65.179", - "port": 81 - }, - { - "ip": "119.193.65.179", - "port": 4000 - }, - { - "ip": "119.193.65.179", - "port": 8000 - }, - { - "ip": "119.193.65.179", - "port": 9000 - }, - { - "ip": "119.193.65.179", - "port": 9001 - }, - { - "ip": "134.122.10.94", - "port": 80 - }, - { - "ip": "134.122.10.94", - "port": 443 - }, - { - "ip": "134.122.10.94", - "port": 8033 - }, - { - "ip": "134.122.10.94", - "port": 8057 - }, - { - "ip": "134.122.10.94", - "port": 8191 - }, - { - "ip": "134.122.10.94", - "port": 8300 - }, - { - "ip": "167.172.120.117", - "port": 80 - }, - { - "ip": "167.172.120.117", - "port": 443 - }, - { - "ip": "167.172.120.117", - "port": 5000 - }, - { - "ip": "167.172.120.117", - "port": 8000 - }, - { - "ip": "167.172.120.117", - "port": 8050 - }, - { - "ip": "185.202.178.137", - "port": 80 - }, - { - "ip": "185.202.178.137", - "port": 443 - }, - { - "ip": "185.202.178.137", - "port": 8443 - }, - { - "ip": "185.202.178.137", - "port": 8880 - }, - { - "ip": "185.202.178.137", - "port": 49111 - }, - { - "ip": "185.202.178.137", - "port": 49191 - }, - { - "ip": "185.202.178.137", - "port": 50532 - }, - { - "ip": "3.18.67.10", - "port": 80 - }, - { - "ip": "3.18.67.10", - "port": 3000 - }, - { - "ip": "18.219.101.80", - "port": 3000 - }, - { - "ip": "18.219.101.80", - "port": 8080 - }, - { - "ip": "128.199.59.104", - "port": 80 - }, - { - "ip": "128.199.59.104", - "port": 3005 - }, - { - "ip": "128.199.59.104", - "port": 3010 - }, - { - "ip": "128.199.59.104", - "port": 3030 - }, - { - "ip": "128.199.59.104", - "port": 3040 - }, - { - "ip": "128.199.59.104", - "port": 4080 - }, - { - "ip": "128.199.59.104", - "port": 5353 - }, - { - "ip": "128.199.59.104", - "port": 5555 - }, - { - "ip": "128.199.59.104", - "port": 8080 - }, - { - "ip": "159.69.185.68", - "port": 80 - }, - { - "ip": "159.69.185.68", - "port": 81 - }, - { - "ip": "159.69.185.68", - "port": 4000 - }, - { - "ip": "159.69.185.68", - "port": 8000 - }, - { - "ip": "159.69.185.68", - "port": 8066 - }, - { - "ip": "159.69.185.68", - "port": 9443 - }, - { - "ip": "201.62.240.69", - "port": 80 - }, - { - "ip": "201.62.240.69", - "port": 443 - }, - { - "ip": "201.62.240.69", - "port": 3002 - }, - { - "ip": "201.62.240.69", - "port": 3003 - }, - { - "ip": "201.62.240.69", - "port": 3004 - }, - { - "ip": "201.62.240.69", - "port": 3005 - }, - { - "ip": "201.62.240.69", - "port": 3006 - }, - { - "ip": "201.62.240.69", - "port": 4000 - }, - { - "ip": "15.228.21.196", - "port": 80 - }, - { - "ip": "15.228.21.196", - "port": 3131 - }, - { - "ip": "15.228.21.196", - "port": 8080 - }, - { - "ip": "18.139.226.124", - "port": 80 - }, - { - "ip": "18.139.226.124", - "port": 443 - }, - { - "ip": "18.139.226.124", - "port": 8080 - }, - { - "ip": "47.254.195.115", - "port": 80 - }, - { - "ip": "47.254.195.115", - "port": 8080 - }, - { - "ip": "47.254.195.115", - "port": 8081 - }, - { - "ip": "47.254.195.115", - "port": 8083 - }, - { - "ip": "47.254.195.115", - "port": 8444 - }, - { - "ip": "47.254.195.115", - "port": 8446 - }, - { - "ip": "47.254.195.115", - "port": 47001 - }, - { - "ip": "63.33.100.67", - "port": 80 - }, - { - "ip": "63.33.100.67", - "port": 443 - }, - { - "ip": "63.33.100.67", - "port": 8000 - }, - { - "ip": "63.33.100.67", - "port": 8080 - }, - { - "ip": "141.145.202.169", - "port": 80 - }, - { - "ip": "141.145.202.169", - "port": 5000 - }, - { - "ip": "141.145.202.169", - "port": 8080 - }, - { - "ip": "141.145.202.169", - "port": 20000 - }, - { - "ip": "3.39.240.195", - "port": 80 - }, - { - "ip": "3.39.240.195", - "port": 81 - }, - { - "ip": "3.39.240.195", - "port": 82 - }, - { - "ip": "3.39.240.195", - "port": 83 - }, - { - "ip": "81.30.80.124", - "port": 80 - }, - { - "ip": "81.30.80.124", - "port": 12000 - }, - { - "ip": "120.237.173.162", - "port": 82 - }, - { - "ip": "120.237.173.162", - "port": 3159 - }, - { - "ip": "120.237.173.162", - "port": 6002 - }, - { - "ip": "120.237.173.162", - "port": 7003 - }, - { - "ip": "120.237.173.162", - "port": 8061 - }, - { - "ip": "120.237.173.162", - "port": 8062 - }, - { - "ip": "120.237.173.162", - "port": 8064 - }, - { - "ip": "120.237.173.162", - "port": 8066 - }, - { - "ip": "120.237.173.162", - "port": 8074 - }, - { - "ip": "120.237.173.162", - "port": 8081 - }, - { - "ip": "120.237.173.162", - "port": 8082 - }, - { - "ip": "120.237.173.162", - "port": 8083 - }, - { - "ip": "120.237.173.162", - "port": 8084 - }, - { - "ip": "120.237.173.162", - "port": 8085 - }, - { - "ip": "120.237.173.162", - "port": 8161 - }, - { - "ip": "120.237.173.162", - "port": 8184 - }, - { - "ip": "120.237.173.162", - "port": 8280 - }, - { - "ip": "120.237.173.162", - "port": 8282 - }, - { - "ip": "120.237.173.162", - "port": 8380 - }, - { - "ip": "120.237.173.162", - "port": 8486 - }, - { - "ip": "120.237.173.162", - "port": 8585 - }, - { - "ip": "120.237.173.162", - "port": 8586 - }, - { - "ip": "120.237.173.162", - "port": 8882 - }, - { - "ip": "120.237.173.162", - "port": 9066 - }, - { - "ip": "120.237.173.162", - "port": 9085 - }, - { - "ip": "120.237.173.162", - "port": 9090 - }, - { - "ip": "120.237.173.162", - "port": 9901 - }, - { - "ip": "120.237.173.162", - "port": 10200 - }, - { - "ip": "120.237.173.162", - "port": 20500 - }, - { - "ip": "139.162.34.246", - "port": 80 - }, - { - "ip": "139.162.34.246", - "port": 443 - }, - { - "ip": "139.162.34.246", - "port": 8080 - }, - { - "ip": "18.202.16.40", - "port": 80 - }, - { - "ip": "88.150.229.19", - "port": 80 - }, - { - "ip": "88.150.229.19", - "port": 443 - }, - { - "ip": "88.150.229.19", - "port": 5985 - }, - { - "ip": "88.150.229.19", - "port": 8172 - }, - { - "ip": "88.150.229.19", - "port": 9090 - }, - { - "ip": "195.201.24.234", - "port": 80 - }, - { - "ip": "195.201.24.234", - "port": 443 - }, - { - "ip": "195.201.24.234", - "port": 8990 - }, - { - "ip": "34.105.34.146", - "port": 5500 - }, - { - "ip": "34.105.34.146", - "port": 5523 - }, - { - "ip": "34.105.34.146", - "port": 5552 - }, - { - "ip": "34.105.34.146", - "port": 5671 - }, - { - "ip": "34.105.34.146", - "port": 5675 - }, - { - "ip": "34.105.34.146", - "port": 5808 - }, - { - "ip": "34.105.34.146", - "port": 5856 - }, - { - "ip": "34.105.34.146", - "port": 5903 - }, - { - "ip": "34.105.34.146", - "port": 5914 - }, - { - "ip": "34.105.34.146", - "port": 5981 - }, - { - "ip": "34.105.34.146", - "port": 5985 - }, - { - "ip": "34.105.34.146", - "port": 6007 - }, - { - "ip": "34.105.34.146", - "port": 6012 - }, - { - "ip": "34.105.34.146", - "port": 6021 - }, - { - "ip": "34.105.34.146", - "port": 6038 - }, - { - "ip": "34.105.34.146", - "port": 6060 - }, - { - "ip": "34.105.34.146", - "port": 6184 - }, - { - "ip": "34.105.34.146", - "port": 6430 - }, - { - "ip": "34.105.34.146", - "port": 6443 - }, - { - "ip": "34.105.34.146", - "port": 6566 - }, - { - "ip": "34.105.34.146", - "port": 6638 - }, - { - "ip": "34.105.34.146", - "port": 6686 - }, - { - "ip": "34.105.34.146", - "port": 6691 - }, - { - "ip": "34.105.34.146", - "port": 6702 - }, - { - "ip": "34.105.34.146", - "port": 6760 - }, - { - "ip": "34.105.34.146", - "port": 6777 - }, - { - "ip": "34.105.34.146", - "port": 6959 - }, - { - "ip": "34.105.34.146", - "port": 7005 - }, - { - "ip": "34.105.34.146", - "port": 7021 - }, - { - "ip": "34.105.34.146", - "port": 7036 - }, - { - "ip": "34.105.34.146", - "port": 7045 - }, - { - "ip": "34.105.34.146", - "port": 7071 - }, - { - "ip": "34.105.34.146", - "port": 7086 - }, - { - "ip": "34.105.34.146", - "port": 7171 - }, - { - "ip": "34.105.34.146", - "port": 7177 - }, - { - "ip": "34.105.34.146", - "port": 7292 - }, - { - "ip": "34.105.34.146", - "port": 7302 - }, - { - "ip": "34.105.34.146", - "port": 7362 - }, - { - "ip": "34.105.34.146", - "port": 7451 - }, - { - "ip": "34.105.34.146", - "port": 7477 - }, - { - "ip": "34.105.34.146", - "port": 7490 - }, - { - "ip": "34.105.34.146", - "port": 7596 - }, - { - "ip": "34.105.34.146", - "port": 7669 - }, - { - "ip": "34.105.34.146", - "port": 7715 - }, - { - "ip": "34.105.34.146", - "port": 7726 - }, - { - "ip": "34.105.34.146", - "port": 7782 - }, - { - "ip": "34.105.34.146", - "port": 7798 - }, - { - "ip": "34.105.34.146", - "port": 7813 - }, - { - "ip": "34.105.34.146", - "port": 8049 - }, - { - "ip": "34.105.34.146", - "port": 8050 - }, - { - "ip": "34.105.34.146", - "port": 8066 - }, - { - "ip": "161.97.148.179", - "port": 80 - }, - { - "ip": "161.97.148.179", - "port": 18080 - }, - { - "ip": "184.72.28.64", - "port": 80 - }, - { - "ip": "184.72.28.64", - "port": 3000 - }, - { - "ip": "35.247.147.119", - "port": 80 - }, - { - "ip": "35.247.147.119", - "port": 443 - }, - { - "ip": "35.247.147.119", - "port": 8090 - }, - { - "ip": "89.220.222.152", - "port": 80 - }, - { - "ip": "89.220.222.152", - "port": 443 - }, - { - "ip": "89.220.222.152", - "port": 6789 - }, - { - "ip": "89.220.222.152", - "port": 8080 - }, - { - "ip": "89.220.222.152", - "port": 8082 - }, - { - "ip": "89.220.222.152", - "port": 8083 - }, - { - "ip": "89.220.222.152", - "port": 8085 - }, - { - "ip": "89.220.222.152", - "port": 8086 - }, - { - "ip": "89.220.222.152", - "port": 8087 - }, - { - "ip": "89.220.222.152", - "port": 8088 - }, - { - "ip": "89.220.222.152", - "port": 8089 - }, - { - "ip": "89.220.222.152", - "port": 8096 - }, - { - "ip": "89.220.222.152", - "port": 8123 - }, - { - "ip": "89.220.222.152", - "port": 8443 - }, - { - "ip": "142.93.253.242", - "port": 3001 - }, - { - "ip": "142.93.253.242", - "port": 8080 - }, - { - "ip": "172.188.2.64", - "port": 8080 - }, - { - "ip": "184.60.26.204", - "port": 3000 - }, - { - "ip": "184.60.26.204", - "port": 3100 - }, - { - "ip": "184.60.26.204", - "port": 5000 - }, - { - "ip": "184.60.26.204", - "port": 5100 - }, - { - "ip": "184.60.26.204", - "port": 40000 - }, - { - "ip": "46.101.8.115", - "port": 8080 - }, - { - "ip": "54.165.1.237", - "port": 80 - }, - { - "ip": "107.173.87.204", - "port": 80 - }, - { - "ip": "107.173.87.204", - "port": 443 - }, - { - "ip": "107.173.87.204", - "port": 3000 - }, - { - "ip": "107.173.87.204", - "port": 3040 - }, - { - "ip": "107.173.87.204", - "port": 4000 - }, - { - "ip": "107.173.87.204", - "port": 5076 - }, - { - "ip": "107.173.87.204", - "port": 6789 - }, - { - "ip": "107.173.87.204", - "port": 7878 - }, - { - "ip": "107.173.87.204", - "port": 8040 - }, - { - "ip": "107.173.87.204", - "port": 8080 - }, - { - "ip": "107.173.87.204", - "port": 8096 - }, - { - "ip": "107.173.87.204", - "port": 8112 - }, - { - "ip": "107.173.87.204", - "port": 9000 - }, - { - "ip": "107.173.87.204", - "port": 9117 - }, - { - "ip": "128.199.104.144", - "port": 80 - }, - { - "ip": "128.199.104.144", - "port": 10250 - }, - { - "ip": "128.199.104.144", - "port": 10256 - }, - { - "ip": "128.199.104.144", - "port": 30002 - }, - { - "ip": "128.199.104.144", - "port": 30003 - }, - { - "ip": "128.199.104.144", - "port": 30005 - }, - { - "ip": "128.199.104.144", - "port": 30006 - }, - { - "ip": "128.199.104.144", - "port": 30008 - }, - { - "ip": "128.199.104.144", - "port": 30009 - }, - { - "ip": "128.199.104.144", - "port": 30010 - }, - { - "ip": "128.199.104.144", - "port": 30011 - }, - { - "ip": "128.199.104.144", - "port": 30012 - }, - { - "ip": "128.199.104.144", - "port": 30013 - }, - { - "ip": "128.199.104.144", - "port": 30015 - }, - { - "ip": "128.199.104.144", - "port": 30016 - }, - { - "ip": "128.199.104.144", - "port": 30017 - }, - { - "ip": "128.199.104.144", - "port": 30020 - }, - { - "ip": "128.199.104.144", - "port": 30021 - }, - { - "ip": "128.199.104.144", - "port": 30022 - }, - { - "ip": "128.199.104.144", - "port": 30023 - }, - { - "ip": "128.199.104.144", - "port": 30024 - }, - { - "ip": "128.199.104.144", - "port": 30025 - }, - { - "ip": "128.199.104.144", - "port": 30027 - }, - { - "ip": "128.199.104.144", - "port": 30029 - }, - { - "ip": "128.199.104.144", - "port": 30030 - }, - { - "ip": "128.199.104.144", - "port": 30031 - }, - { - "ip": "128.199.104.144", - "port": 30034 - }, - { - "ip": "128.199.104.144", - "port": 30035 - }, - { - "ip": "128.199.104.144", - "port": 30037 - }, - { - "ip": "128.199.104.144", - "port": 30039 - }, - { - "ip": "128.199.104.144", - "port": 30040 - }, - { - "ip": "128.199.104.144", - "port": 30043 - }, - { - "ip": "128.199.104.144", - "port": 30044 - }, - { - "ip": "128.199.104.144", - "port": 30046 - }, - { - "ip": "128.199.104.144", - "port": 30047 - }, - { - "ip": "128.199.104.144", - "port": 30048 - }, - { - "ip": "128.199.104.144", - "port": 30050 - }, - { - "ip": "128.199.104.144", - "port": 31004 - }, - { - "ip": "128.199.104.144", - "port": 31006 - }, - { - "ip": "128.199.104.144", - "port": 31010 - }, - { - "ip": "128.199.104.144", - "port": 31012 - }, - { - "ip": "128.199.104.144", - "port": 31024 - }, - { - "ip": "161.97.181.15", - "port": 80 - }, - { - "ip": "161.97.181.15", - "port": 443 - }, - { - "ip": "161.97.181.15", - "port": 3005 - }, - { - "ip": "161.97.181.15", - "port": 5000 - }, - { - "ip": "161.97.181.15", - "port": 7000 - }, - { - "ip": "161.97.181.15", - "port": 8080 - }, - { - "ip": "161.97.181.15", - "port": 8085 - }, - { - "ip": "194.163.161.233", - "port": 80 - }, - { - "ip": "194.163.161.233", - "port": 81 - }, - { - "ip": "194.163.161.233", - "port": 3001 - }, - { - "ip": "194.163.161.233", - "port": 3010 - }, - { - "ip": "194.163.161.233", - "port": 3020 - }, - { - "ip": "194.163.161.233", - "port": 3030 - }, - { - "ip": "194.163.161.233", - "port": 3777 - }, - { - "ip": "194.163.161.233", - "port": 4000 - }, - { - "ip": "194.163.161.233", - "port": 8080 - }, - { - "ip": "220.125.228.210", - "port": 80 - }, - { - "ip": "220.125.228.210", - "port": 84 - }, - { - "ip": "220.125.228.210", - "port": 6500 - }, - { - "ip": "220.125.228.210", - "port": 8080 - }, - { - "ip": "220.125.228.210", - "port": 8090 - }, - { - "ip": "3.75.84.23", - "port": 3000 - }, - { - "ip": "3.75.84.23", - "port": 3131 - }, - { - "ip": "3.75.84.23", - "port": 3132 - }, - { - "ip": "3.75.84.23", - "port": 8081 - }, - { - "ip": "3.212.43.193", - "port": 80 - }, - { - "ip": "3.212.43.193", - "port": 443 - }, - { - "ip": "3.212.43.193", - "port": 7000 - }, - { - "ip": "3.212.43.193", - "port": 8050 - }, - { - "ip": "3.212.43.193", - "port": 8090 - }, - { - "ip": "3.212.43.193", - "port": 8600 - }, - { - "ip": "3.212.43.193", - "port": 8700 - }, - { - "ip": "18.223.23.28", - "port": 80 - }, - { - "ip": "18.223.23.28", - "port": 8080 - }, - { - "ip": "34.120.243.135", - "port": 8080 - }, - { - "ip": "59.15.185.231", - "port": 80 - }, - { - "ip": "59.15.185.231", - "port": 81 - }, - { - "ip": "59.15.185.231", - "port": 84 - }, - { - "ip": "59.15.185.231", - "port": 443 - }, - { - "ip": "59.15.185.231", - "port": 8080 - }, - { - "ip": "59.15.185.231", - "port": 9935 - }, - { - "ip": "187.11.239.213", - "port": 9999 - }, - { - "ip": "1.215.252.149", - "port": 8080 - }, - { - "ip": "52.67.0.118", - "port": 4000 - }, - { - "ip": "52.67.0.118", - "port": 6000 - }, - { - "ip": "52.67.0.118", - "port": 6050 - }, - { - "ip": "52.67.0.118", - "port": 7000 - }, - { - "ip": "52.67.0.118", - "port": 7050 - }, - { - "ip": "52.67.0.118", - "port": 7500 - }, - { - "ip": "52.67.0.118", - "port": 7777 - }, - { - "ip": "52.67.0.118", - "port": 8000 - }, - { - "ip": "52.67.0.118", - "port": 8001 - }, - { - "ip": "52.67.0.118", - "port": 8050 - }, - { - "ip": "52.67.0.118", - "port": 8893 - }, - { - "ip": "52.67.0.118", - "port": 9000 - }, - { - "ip": "52.67.0.118", - "port": 9001 - }, - { - "ip": "52.67.0.118", - "port": 9005 - }, - { - "ip": "52.67.0.118", - "port": 9006 - }, - { - "ip": "52.67.0.118", - "port": 9008 - }, - { - "ip": "52.67.0.118", - "port": 9999 - }, - { - "ip": "54.149.55.113", - "port": 5000 - }, - { - "ip": "61.32.15.50", - "port": 80 - }, - { - "ip": "61.32.15.50", - "port": 81 - }, - { - "ip": "61.32.15.50", - "port": 443 - }, - { - "ip": "61.32.15.50", - "port": 8080 - }, - { - "ip": "175.195.159.238", - "port": 80 - }, - { - "ip": "175.195.159.238", - "port": 84 - }, - { - "ip": "175.195.159.238", - "port": 5357 - }, - { - "ip": "175.195.159.238", - "port": 6500 - }, - { - "ip": "175.195.159.238", - "port": 8080 - }, - { - "ip": "175.195.159.238", - "port": 8090 - }, - { - "ip": "185.182.186.16", - "port": 80 - }, - { - "ip": "185.182.186.16", - "port": 443 - }, - { - "ip": "185.182.186.16", - "port": 6969 - }, - { - "ip": "213.203.179.36", - "port": 80 - }, - { - "ip": "213.203.179.36", - "port": 8008 - }, - { - "ip": "1.214.20.74", - "port": 84 - }, - { - "ip": "1.214.20.74", - "port": 8080 - }, - { - "ip": "1.214.20.74", - "port": 9935 - }, - { - "ip": "3.25.201.182", - "port": 80 - }, - { - "ip": "3.25.201.182", - "port": 8080 - }, - { - "ip": "35.90.239.161", - "port": 5000 - }, - { - "ip": "52.47.209.162", - "port": 80 - }, - { - "ip": "52.47.209.162", - "port": 443 - }, - { - "ip": "52.47.209.162", - "port": 3003 - }, - { - "ip": "52.47.209.162", - "port": 3004 - }, - { - "ip": "52.47.209.162", - "port": 3013 - }, - { - "ip": "52.47.209.162", - "port": 3014 - }, - { - "ip": "52.47.209.162", - "port": 10444 - }, - { - "ip": "52.47.209.162", - "port": 10445 - }, - { - "ip": "91.185.191.245", - "port": 80 - }, - { - "ip": "91.185.191.245", - "port": 5985 - }, - { - "ip": "91.185.191.245", - "port": 8080 - }, - { - "ip": "91.185.191.245", - "port": 8081 - }, - { - "ip": "91.185.191.245", - "port": 8082 - }, - { - "ip": "91.185.191.245", - "port": 8443 - }, - { - "ip": "91.185.191.245", - "port": 8880 - }, - { - "ip": "91.185.191.245", - "port": 47001 - }, - { - "ip": "101.132.183.6", - "port": 80 - }, - { - "ip": "101.132.183.6", - "port": 443 - }, - { - "ip": "101.132.183.6", - "port": 8080 - }, - { - "ip": "141.144.242.37", - "port": 8080 - }, - { - "ip": "44.235.4.105", - "port": 80 - }, - { - "ip": "52.77.175.184", - "port": 80 - }, - { - "ip": "116.203.235.173", - "port": 80 - }, - { - "ip": "116.203.235.173", - "port": 443 - }, - { - "ip": "116.203.235.173", - "port": 1234 - }, - { - "ip": "116.203.235.173", - "port": 5353 - }, - { - "ip": "116.203.235.173", - "port": 8448 - }, - { - "ip": "116.203.235.173", - "port": 9812 - }, - { - "ip": "213.136.89.10", - "port": 80 - }, - { - "ip": "213.136.89.10", - "port": 443 - }, - { - "ip": "213.136.89.10", - "port": 3080 - }, - { - "ip": "213.136.89.10", - "port": 3090 - }, - { - "ip": "213.136.89.10", - "port": 3389 - }, - { - "ip": "213.136.89.10", - "port": 3443 - }, - { - "ip": "213.136.89.10", - "port": 8080 - }, - { - "ip": "213.136.89.10", - "port": 8880 - }, - { - "ip": "3.223.204.248", - "port": 3000 - }, - { - "ip": "18.163.28.243", - "port": 80 - }, - { - "ip": "18.163.28.243", - "port": 443 - }, - { - "ip": "18.163.28.243", - "port": 3000 - }, - { - "ip": "18.163.28.243", - "port": 8001 - }, - { - "ip": "18.163.28.243", - "port": 8081 - }, - { - "ip": "35.199.100.6", - "port": 80 - }, - { - "ip": "35.199.100.6", - "port": 8080 - }, - { - "ip": "35.199.100.6", - "port": 8081 - }, - { - "ip": "95.217.187.97", - "port": 80 - }, - { - "ip": "95.217.187.97", - "port": 8080 - }, - { - "ip": "143.198.79.172", - "port": 80 - }, - { - "ip": "143.198.79.172", - "port": 443 - }, - { - "ip": "143.198.79.172", - "port": 3001 - }, - { - "ip": "143.198.79.172", - "port": 3838 - }, - { - "ip": "143.198.79.172", - "port": 16112 - }, - { - "ip": "194.62.19.4", - "port": 80 - }, - { - "ip": "194.62.19.4", - "port": 443 - }, - { - "ip": "194.62.19.4", - "port": 8080 - }, - { - "ip": "221.161.72.101", - "port": 80 - }, - { - "ip": "221.161.72.101", - "port": 84 - }, - { - "ip": "221.161.72.101", - "port": 8080 - }, - { - "ip": "221.161.72.101", - "port": 9935 - }, - { - "ip": "18.116.215.112", - "port": 80 - }, - { - "ip": "35.198.51.185", - "port": 80 - }, - { - "ip": "35.198.51.185", - "port": 8080 - }, - { - "ip": "35.198.51.185", - "port": 8081 - }, - { - "ip": "35.230.48.98", - "port": 5511 - }, - { - "ip": "35.230.48.98", - "port": 5647 - }, - { - "ip": "35.230.48.98", - "port": 5680 - }, - { - "ip": "35.230.48.98", - "port": 5721 - }, - { - "ip": "35.230.48.98", - "port": 5910 - }, - { - "ip": "35.230.48.98", - "port": 5912 - }, - { - "ip": "35.230.48.98", - "port": 5957 - }, - { - "ip": "35.230.48.98", - "port": 5997 - }, - { - "ip": "35.230.48.98", - "port": 6010 - }, - { - "ip": "35.230.48.98", - "port": 6021 - }, - { - "ip": "35.230.48.98", - "port": 6050 - }, - { - "ip": "35.230.48.98", - "port": 6212 - }, - { - "ip": "35.230.48.98", - "port": 6278 - }, - { - "ip": "35.230.48.98", - "port": 6432 - }, - { - "ip": "35.230.48.98", - "port": 6474 - }, - { - "ip": "35.230.48.98", - "port": 6699 - }, - { - "ip": "35.230.48.98", - "port": 6804 - }, - { - "ip": "35.230.48.98", - "port": 6928 - }, - { - "ip": "35.230.48.98", - "port": 6945 - }, - { - "ip": "35.230.48.98", - "port": 7003 - }, - { - "ip": "35.230.48.98", - "port": 7010 - }, - { - "ip": "35.230.48.98", - "port": 7020 - }, - { - "ip": "35.230.48.98", - "port": 7088 - }, - { - "ip": "35.230.48.98", - "port": 7166 - }, - { - "ip": "35.230.48.98", - "port": 7441 - }, - { - "ip": "35.230.48.98", - "port": 7591 - }, - { - "ip": "35.230.48.98", - "port": 7676 - }, - { - "ip": "35.230.48.98", - "port": 7687 - }, - { - "ip": "35.230.48.98", - "port": 7733 - }, - { - "ip": "35.230.48.98", - "port": 7772 - }, - { - "ip": "35.230.48.98", - "port": 7778 - }, - { - "ip": "35.230.48.98", - "port": 7788 - }, - { - "ip": "35.230.48.98", - "port": 7938 - }, - { - "ip": "35.230.48.98", - "port": 7998 - }, - { - "ip": "35.230.48.98", - "port": 8009 - }, - { - "ip": "35.230.48.98", - "port": 8010 - }, - { - "ip": "35.230.48.98", - "port": 8013 - }, - { - "ip": "35.230.48.98", - "port": 8016 - }, - { - "ip": "35.230.48.98", - "port": 8027 - }, - { - "ip": "35.230.48.98", - "port": 8028 - }, - { - "ip": "35.230.48.98", - "port": 8029 - }, - { - "ip": "35.230.48.98", - "port": 8056 - }, - { - "ip": "35.230.48.98", - "port": 8058 - }, - { - "ip": "35.230.48.98", - "port": 8061 - }, - { - "ip": "35.230.48.98", - "port": 8067 - }, - { - "ip": "36.38.213.141", - "port": 80 - }, - { - "ip": "36.38.213.141", - "port": 81 - }, - { - "ip": "36.38.213.141", - "port": 84 - }, - { - "ip": "36.38.213.141", - "port": 443 - }, - { - "ip": "36.38.213.141", - "port": 8080 - }, - { - "ip": "36.38.213.141", - "port": 9935 - }, - { - "ip": "4.236.220.159", - "port": 8080 - }, - { - "ip": "18.216.118.14", - "port": 8080 - }, - { - "ip": "92.240.66.184", - "port": 80 - }, - { - "ip": "92.240.66.184", - "port": 443 - }, - { - "ip": "92.240.66.184", - "port": 16147 - }, - { - "ip": "92.240.66.184", - "port": 16186 - }, - { - "ip": "92.240.66.184", - "port": 16187 - }, - { - "ip": "92.240.66.184", - "port": 33004 - }, - { - "ip": "112.216.107.62", - "port": 80 - }, - { - "ip": "112.216.107.62", - "port": 81 - }, - { - "ip": "112.216.107.62", - "port": 84 - }, - { - "ip": "112.216.107.62", - "port": 443 - }, - { - "ip": "112.216.107.62", - "port": 8080 - }, - { - "ip": "3.17.200.189", - "port": 80 - }, - { - "ip": "3.17.200.189", - "port": 443 - }, - { - "ip": "3.17.200.189", - "port": 8080 - }, - { - "ip": "3.209.40.15", - "port": 3001 - }, - { - "ip": "3.209.40.15", - "port": 8081 - }, - { - "ip": "43.201.25.116", - "port": 80 - }, - { - "ip": "43.201.25.116", - "port": 81 - }, - { - "ip": "43.201.25.116", - "port": 8080 - }, - { - "ip": "112.216.107.46", - "port": 80 - }, - { - "ip": "112.216.107.46", - "port": 443 - }, - { - "ip": "112.216.107.46", - "port": 8080 - }, - { - "ip": "112.216.107.46", - "port": 9935 - }, - { - "ip": "118.37.27.44", - "port": 80 - }, - { - "ip": "118.37.27.44", - "port": 81 - }, - { - "ip": "118.37.27.44", - "port": 84 - }, - { - "ip": "118.37.27.44", - "port": 443 - }, - { - "ip": "118.37.27.44", - "port": 8080 - }, - { - "ip": "118.37.27.44", - "port": 9935 - }, - { - "ip": "185.223.95.137", - "port": 5000 - }, - { - "ip": "185.223.95.137", - "port": 7000 - }, - { - "ip": "185.223.95.137", - "port": 8080 - }, - { - "ip": "185.223.95.137", - "port": 8083 - }, - { - "ip": "185.223.95.137", - "port": 9100 - }, - { - "ip": "185.223.95.137", - "port": 25080 - }, - { - "ip": "218.49.254.196", - "port": 80 - }, - { - "ip": "218.49.254.196", - "port": 81 - }, - { - "ip": "218.49.254.196", - "port": 84 - }, - { - "ip": "218.49.254.196", - "port": 443 - }, - { - "ip": "218.49.254.196", - "port": 8080 - }, - { - "ip": "218.49.254.196", - "port": 9935 - }, - { - "ip": "14.50.99.20", - "port": 80 - }, - { - "ip": "14.50.99.20", - "port": 84 - }, - { - "ip": "14.50.99.20", - "port": 8080 - }, - { - "ip": "14.50.99.20", - "port": 9935 - }, - { - "ip": "16.16.247.210", - "port": 80 - }, - { - "ip": "39.104.107.148", - "port": 8080 - }, - { - "ip": "39.104.107.148", - "port": 8081 - }, - { - "ip": "86.127.243.135", - "port": 8080 - }, - { - "ip": "119.192.242.157", - "port": 80 - }, - { - "ip": "119.192.242.157", - "port": 84 - }, - { - "ip": "119.192.242.157", - "port": 8080 - }, - { - "ip": "119.192.242.157", - "port": 9935 - }, - { - "ip": "134.122.88.54", - "port": 80 - }, - { - "ip": "134.122.88.54", - "port": 8080 - }, - { - "ip": "174.136.135.59", - "port": 80 - }, - { - "ip": "174.136.135.59", - "port": 2000 - }, - { - "ip": "174.136.135.59", - "port": 2001 - }, - { - "ip": "174.136.135.59", - "port": 8000 - }, - { - "ip": "174.136.135.59", - "port": 8010 - }, - { - "ip": "174.136.135.59", - "port": 8030 - }, - { - "ip": "174.136.135.59", - "port": 8051 - }, - { - "ip": "174.136.135.59", - "port": 8052 - }, - { - "ip": "174.136.135.59", - "port": 8053 - }, - { - "ip": "174.136.135.59", - "port": 8054 - }, - { - "ip": "174.136.135.59", - "port": 8055 - }, - { - "ip": "174.136.135.59", - "port": 8056 - }, - { - "ip": "174.136.135.59", - "port": 8057 - }, - { - "ip": "174.136.135.59", - "port": 8058 - }, - { - "ip": "174.136.135.59", - "port": 9000 - }, - { - "ip": "174.136.135.59", - "port": 9090 - }, - { - "ip": "174.136.135.59", - "port": 9595 - }, - { - "ip": "174.136.135.59", - "port": 9596 - }, - { - "ip": "34.83.104.151", - "port": 5505 - }, - { - "ip": "34.83.104.151", - "port": 5543 - }, - { - "ip": "34.83.104.151", - "port": 5590 - }, - { - "ip": "34.83.104.151", - "port": 5592 - }, - { - "ip": "34.83.104.151", - "port": 5595 - }, - { - "ip": "34.83.104.151", - "port": 5597 - }, - { - "ip": "34.83.104.151", - "port": 5610 - }, - { - "ip": "34.83.104.151", - "port": 5687 - }, - { - "ip": "34.83.104.151", - "port": 5696 - }, - { - "ip": "34.83.104.151", - "port": 5716 - }, - { - "ip": "34.83.104.151", - "port": 5719 - }, - { - "ip": "34.83.104.151", - "port": 5792 - }, - { - "ip": "34.83.104.151", - "port": 5901 - }, - { - "ip": "34.83.104.151", - "port": 5905 - }, - { - "ip": "34.83.104.151", - "port": 5906 - }, - { - "ip": "34.83.104.151", - "port": 5998 - }, - { - "ip": "34.83.104.151", - "port": 6008 - }, - { - "ip": "34.83.104.151", - "port": 6011 - }, - { - "ip": "34.83.104.151", - "port": 6081 - }, - { - "ip": "34.83.104.151", - "port": 6156 - }, - { - "ip": "34.83.104.151", - "port": 6234 - }, - { - "ip": "34.83.104.151", - "port": 6362 - }, - { - "ip": "34.83.104.151", - "port": 6405 - }, - { - "ip": "34.83.104.151", - "port": 6466 - }, - { - "ip": "34.83.104.151", - "port": 6503 - }, - { - "ip": "34.83.104.151", - "port": 6642 - }, - { - "ip": "34.83.104.151", - "port": 6670 - }, - { - "ip": "34.83.104.151", - "port": 6719 - }, - { - "ip": "34.83.104.151", - "port": 6799 - }, - { - "ip": "34.83.104.151", - "port": 6827 - }, - { - "ip": "34.83.104.151", - "port": 6958 - }, - { - "ip": "34.83.104.151", - "port": 6969 - }, - { - "ip": "34.83.104.151", - "port": 7010 - }, - { - "ip": "34.83.104.151", - "port": 7029 - }, - { - "ip": "34.83.104.151", - "port": 7057 - }, - { - "ip": "34.83.104.151", - "port": 7070 - }, - { - "ip": "34.83.104.151", - "port": 7087 - }, - { - "ip": "34.83.104.151", - "port": 7099 - }, - { - "ip": "34.83.104.151", - "port": 7100 - }, - { - "ip": "34.83.104.151", - "port": 7235 - }, - { - "ip": "34.83.104.151", - "port": 7236 - }, - { - "ip": "34.83.104.151", - "port": 7255 - }, - { - "ip": "34.83.104.151", - "port": 7273 - }, - { - "ip": "34.83.104.151", - "port": 7283 - }, - { - "ip": "34.83.104.151", - "port": 7297 - }, - { - "ip": "34.83.104.151", - "port": 7373 - }, - { - "ip": "34.83.104.151", - "port": 7390 - }, - { - "ip": "34.83.104.151", - "port": 7473 - }, - { - "ip": "34.83.104.151", - "port": 7565 - }, - { - "ip": "34.83.104.151", - "port": 7776 - }, - { - "ip": "34.83.104.151", - "port": 7780 - }, - { - "ip": "34.83.104.151", - "port": 7781 - }, - { - "ip": "34.83.104.151", - "port": 7782 - }, - { - "ip": "34.83.104.151", - "port": 7799 - }, - { - "ip": "34.83.104.151", - "port": 7835 - }, - { - "ip": "34.83.104.151", - "port": 7910 - }, - { - "ip": "34.83.104.151", - "port": 7946 - }, - { - "ip": "34.83.104.151", - "port": 7950 - }, - { - "ip": "34.83.104.151", - "port": 8005 - }, - { - "ip": "34.83.104.151", - "port": 8015 - }, - { - "ip": "34.83.104.151", - "port": 8051 - }, - { - "ip": "34.83.104.151", - "port": 8062 - }, - { - "ip": "61.101.2.98", - "port": 80 - }, - { - "ip": "61.101.2.98", - "port": 84 - }, - { - "ip": "61.101.2.98", - "port": 8080 - }, - { - "ip": "61.101.2.98", - "port": 9935 - }, - { - "ip": "62.113.103.37", - "port": 80 - }, - { - "ip": "62.113.103.37", - "port": 443 - }, - { - "ip": "62.113.103.37", - "port": 3000 - }, - { - "ip": "62.113.103.37", - "port": 3001 - }, - { - "ip": "62.113.103.37", - "port": 8080 - }, - { - "ip": "62.113.103.37", - "port": 8090 - }, - { - "ip": "104.219.251.119", - "port": 80 - }, - { - "ip": "104.219.251.119", - "port": 443 - }, - { - "ip": "104.219.251.119", - "port": 2077 - }, - { - "ip": "104.219.251.119", - "port": 2078 - }, - { - "ip": "104.219.251.119", - "port": 2082 - }, - { - "ip": "104.219.251.119", - "port": 2083 - }, - { - "ip": "104.219.251.119", - "port": 2086 - }, - { - "ip": "104.219.251.119", - "port": 2087 - }, - { - "ip": "104.219.251.119", - "port": 2095 - }, - { - "ip": "104.219.251.119", - "port": 2096 - }, - { - "ip": "104.219.251.119", - "port": 8080 - }, - { - "ip": "177.124.244.203", - "port": 3000 - }, - { - "ip": "177.124.244.203", - "port": 4443 - }, - { - "ip": "177.124.244.203", - "port": 8081 - }, - { - "ip": "177.124.244.203", - "port": 8082 - }, - { - "ip": "177.124.244.203", - "port": 9999 - }, - { - "ip": "189.8.93.93", - "port": 222 - }, - { - "ip": "189.8.93.93", - "port": 1201 - }, - { - "ip": "189.8.93.93", - "port": 1402 - }, - { - "ip": "189.8.93.93", - "port": 1409 - }, - { - "ip": "189.8.93.93", - "port": 1444 - }, - { - "ip": "189.8.93.93", - "port": 1632 - }, - { - "ip": "189.8.93.93", - "port": 2083 - }, - { - "ip": "189.8.93.93", - "port": 3146 - }, - { - "ip": "189.8.93.93", - "port": 8091 - }, - { - "ip": "189.8.93.93", - "port": 8092 - }, - { - "ip": "189.8.93.93", - "port": 8094 - }, - { - "ip": "189.8.93.93", - "port": 8121 - }, - { - "ip": "189.8.93.93", - "port": 8122 - }, - { - "ip": "189.8.93.93", - "port": 8131 - }, - { - "ip": "189.8.93.93", - "port": 8132 - }, - { - "ip": "189.8.93.93", - "port": 8133 - }, - { - "ip": "189.8.93.93", - "port": 8170 - }, - { - "ip": "189.8.93.93", - "port": 8171 - }, - { - "ip": "189.8.93.93", - "port": 8172 - }, - { - "ip": "189.8.93.93", - "port": 8173 - }, - { - "ip": "189.8.93.93", - "port": 8174 - }, - { - "ip": "189.8.93.93", - "port": 8175 - }, - { - "ip": "189.8.93.93", - "port": 8176 - }, - { - "ip": "189.8.93.93", - "port": 8177 - }, - { - "ip": "189.8.93.93", - "port": 8178 - }, - { - "ip": "189.8.93.93", - "port": 8180 - }, - { - "ip": "189.8.93.93", - "port": 8181 - }, - { - "ip": "189.8.93.93", - "port": 8182 - }, - { - "ip": "189.8.93.93", - "port": 8183 - }, - { - "ip": "189.8.93.93", - "port": 8184 - }, - { - "ip": "189.8.93.93", - "port": 8185 - }, - { - "ip": "189.8.93.93", - "port": 8190 - }, - { - "ip": "189.8.93.93", - "port": 8191 - }, - { - "ip": "189.8.93.93", - "port": 8192 - }, - { - "ip": "189.8.93.93", - "port": 8193 - }, - { - "ip": "189.8.93.93", - "port": 8194 - }, - { - "ip": "189.8.93.93", - "port": 8195 - }, - { - "ip": "189.8.93.93", - "port": 8196 - }, - { - "ip": "189.8.93.93", - "port": 8203 - }, - { - "ip": "189.8.93.93", - "port": 9999 - }, - { - "ip": "189.8.93.93", - "port": 10000 - }, - { - "ip": "189.8.93.93", - "port": 10011 - }, - { - "ip": "189.8.93.93", - "port": 10012 - }, - { - "ip": "189.8.93.93", - "port": 10013 - }, - { - "ip": "189.8.93.93", - "port": 10014 - }, - { - "ip": "189.8.93.93", - "port": 10015 - }, - { - "ip": "189.8.93.93", - "port": 10016 - }, - { - "ip": "189.8.93.93", - "port": 10017 - }, - { - "ip": "189.8.93.93", - "port": 10018 - }, - { - "ip": "189.8.93.93", - "port": 10101 - }, - { - "ip": "189.8.93.93", - "port": 10103 - }, - { - "ip": "189.8.93.93", - "port": 10105 - }, - { - "ip": "189.8.93.93", - "port": 10106 - }, - { - "ip": "189.8.93.93", - "port": 10115 - }, - { - "ip": "189.8.93.93", - "port": 10120 - }, - { - "ip": "189.8.93.93", - "port": 10123 - }, - { - "ip": "189.8.93.93", - "port": 10131 - }, - { - "ip": "189.8.93.93", - "port": 18132 - }, - { - "ip": "189.8.93.93", - "port": 18135 - }, - { - "ip": "189.8.93.93", - "port": 18283 - }, - { - "ip": "189.8.93.93", - "port": 18601 - }, - { - "ip": "189.8.93.93", - "port": 40013 - }, - { - "ip": "189.8.93.93", - "port": 61234 - }, - { - "ip": "220.83.251.151", - "port": 80 - }, - { - "ip": "220.83.251.151", - "port": 84 - }, - { - "ip": "220.83.251.151", - "port": 443 - }, - { - "ip": "220.83.251.151", - "port": 8080 - }, - { - "ip": "34.117.50.6", - "port": 80 - }, - { - "ip": "34.117.50.6", - "port": 443 - }, - { - "ip": "34.127.80.91", - "port": 5433 - }, - { - "ip": "34.127.80.91", - "port": 5475 - }, - { - "ip": "34.127.80.91", - "port": 5495 - }, - { - "ip": "34.127.80.91", - "port": 5682 - }, - { - "ip": "34.127.80.91", - "port": 5696 - }, - { - "ip": "34.127.80.91", - "port": 5701 - }, - { - "ip": "34.127.80.91", - "port": 5804 - }, - { - "ip": "34.127.80.91", - "port": 5835 - }, - { - "ip": "34.127.80.91", - "port": 5916 - }, - { - "ip": "34.127.80.91", - "port": 5920 - }, - { - "ip": "34.127.80.91", - "port": 5979 - }, - { - "ip": "34.127.80.91", - "port": 5985 - }, - { - "ip": "34.127.80.91", - "port": 6010 - }, - { - "ip": "34.127.80.91", - "port": 6020 - }, - { - "ip": "34.127.80.91", - "port": 6022 - }, - { - "ip": "34.127.80.91", - "port": 6058 - }, - { - "ip": "34.127.80.91", - "port": 6081 - }, - { - "ip": "34.127.80.91", - "port": 6108 - }, - { - "ip": "34.127.80.91", - "port": 6194 - }, - { - "ip": "34.127.80.91", - "port": 6400 - }, - { - "ip": "34.127.80.91", - "port": 6436 - }, - { - "ip": "34.127.80.91", - "port": 6461 - }, - { - "ip": "34.127.80.91", - "port": 6478 - }, - { - "ip": "34.127.80.91", - "port": 6511 - }, - { - "ip": "34.127.80.91", - "port": 6544 - }, - { - "ip": "34.127.80.91", - "port": 6658 - }, - { - "ip": "34.127.80.91", - "port": 6665 - }, - { - "ip": "34.127.80.91", - "port": 6688 - }, - { - "ip": "34.127.80.91", - "port": 6814 - }, - { - "ip": "34.127.80.91", - "port": 6831 - }, - { - "ip": "34.127.80.91", - "port": 6881 - }, - { - "ip": "34.127.80.91", - "port": 7006 - }, - { - "ip": "34.127.80.91", - "port": 7010 - }, - { - "ip": "34.127.80.91", - "port": 7014 - }, - { - "ip": "34.127.80.91", - "port": 7090 - }, - { - "ip": "34.127.80.91", - "port": 7125 - }, - { - "ip": "34.127.80.91", - "port": 7156 - }, - { - "ip": "34.127.80.91", - "port": 7226 - }, - { - "ip": "34.127.80.91", - "port": 7235 - }, - { - "ip": "34.127.80.91", - "port": 7320 - }, - { - "ip": "34.127.80.91", - "port": 7443 - }, - { - "ip": "34.127.80.91", - "port": 7467 - }, - { - "ip": "34.127.80.91", - "port": 7547 - }, - { - "ip": "34.127.80.91", - "port": 7700 - }, - { - "ip": "34.127.80.91", - "port": 7711 - }, - { - "ip": "34.127.80.91", - "port": 7972 - }, - { - "ip": "34.127.80.91", - "port": 7980 - }, - { - "ip": "34.127.80.91", - "port": 8000 - }, - { - "ip": "34.127.80.91", - "port": 8006 - }, - { - "ip": "34.127.80.91", - "port": 8013 - }, - { - "ip": "34.127.80.91", - "port": 8022 - }, - { - "ip": "34.127.80.91", - "port": 8025 - }, - { - "ip": "34.127.80.91", - "port": 8075 - }, - { - "ip": "46.101.203.198", - "port": 80 - }, - { - "ip": "46.101.203.198", - "port": 8080 - }, - { - "ip": "46.101.203.198", - "port": 8083 - }, - { - "ip": "119.201.105.195", - "port": 80 - }, - { - "ip": "119.201.105.195", - "port": 84 - }, - { - "ip": "119.201.105.195", - "port": 8080 - }, - { - "ip": "119.201.105.195", - "port": 9935 - }, - { - "ip": "220.89.206.202", - "port": 80 - }, - { - "ip": "220.89.206.202", - "port": 84 - }, - { - "ip": "220.89.206.202", - "port": 8080 - }, - { - "ip": "220.89.206.202", - "port": 9935 - }, - { - "ip": "34.83.209.225", - "port": 5467 - }, - { - "ip": "34.83.209.225", - "port": 5485 - }, - { - "ip": "34.83.209.225", - "port": 5596 - }, - { - "ip": "34.83.209.225", - "port": 5628 - }, - { - "ip": "34.83.209.225", - "port": 5648 - }, - { - "ip": "34.83.209.225", - "port": 5649 - }, - { - "ip": "34.83.209.225", - "port": 5678 - }, - { - "ip": "34.83.209.225", - "port": 5909 - }, - { - "ip": "34.83.209.225", - "port": 5921 - }, - { - "ip": "34.83.209.225", - "port": 5940 - }, - { - "ip": "34.83.209.225", - "port": 6009 - }, - { - "ip": "34.83.209.225", - "port": 6010 - }, - { - "ip": "34.83.209.225", - "port": 6070 - }, - { - "ip": "34.83.209.225", - "port": 6113 - }, - { - "ip": "34.83.209.225", - "port": 6160 - }, - { - "ip": "34.83.209.225", - "port": 6173 - }, - { - "ip": "34.83.209.225", - "port": 6293 - }, - { - "ip": "34.83.209.225", - "port": 6348 - }, - { - "ip": "34.83.209.225", - "port": 6467 - }, - { - "ip": "34.83.209.225", - "port": 6608 - }, - { - "ip": "34.83.209.225", - "port": 6992 - }, - { - "ip": "34.83.209.225", - "port": 7100 - }, - { - "ip": "34.83.209.225", - "port": 7156 - }, - { - "ip": "34.83.209.225", - "port": 7172 - }, - { - "ip": "34.83.209.225", - "port": 7283 - }, - { - "ip": "34.83.209.225", - "port": 7428 - }, - { - "ip": "34.83.209.225", - "port": 7433 - }, - { - "ip": "34.83.209.225", - "port": 7480 - }, - { - "ip": "34.83.209.225", - "port": 7590 - }, - { - "ip": "34.83.209.225", - "port": 7780 - }, - { - "ip": "34.83.209.225", - "port": 7801 - }, - { - "ip": "34.83.209.225", - "port": 7840 - }, - { - "ip": "34.83.209.225", - "port": 7938 - }, - { - "ip": "34.83.209.225", - "port": 7945 - }, - { - "ip": "34.83.209.225", - "port": 8024 - }, - { - "ip": "34.83.209.225", - "port": 8026 - }, - { - "ip": "34.83.209.225", - "port": 8029 - }, - { - "ip": "34.83.209.225", - "port": 8073 - }, - { - "ip": "189.240.37.68", - "port": 80 - }, - { - "ip": "189.240.37.68", - "port": 443 - }, - { - "ip": "189.240.37.68", - "port": 4001 - }, - { - "ip": "189.240.37.68", - "port": 8080 - }, - { - "ip": "189.240.37.68", - "port": 8088 - }, - { - "ip": "189.240.37.68", - "port": 8089 - }, - { - "ip": "3.94.192.175", - "port": 8080 - }, - { - "ip": "34.121.69.236", - "port": 80 - }, - { - "ip": "34.121.69.236", - "port": 8080 - }, - { - "ip": "34.121.69.236", - "port": 8081 - }, - { - "ip": "34.148.56.10", - "port": 80 - }, - { - "ip": "34.148.56.10", - "port": 8080 - }, - { - "ip": "34.148.56.10", - "port": 8081 - }, - { - "ip": "159.65.139.98", - "port": 80 - }, - { - "ip": "159.65.139.98", - "port": 443 - }, - { - "ip": "159.65.139.98", - "port": 3001 - }, - { - "ip": "159.65.139.98", - "port": 3002 - }, - { - "ip": "159.65.139.98", - "port": 8080 - }, - { - "ip": "159.65.139.98", - "port": 8800 - }, - { - "ip": "159.65.139.98", - "port": 9902 - }, - { - "ip": "165.227.136.196", - "port": 8080 - }, - { - "ip": "167.86.73.155", - "port": 80 - }, - { - "ip": "167.86.73.155", - "port": 443 - }, - { - "ip": "167.86.73.155", - "port": 2710 - }, - { - "ip": "167.86.73.155", - "port": 6001 - }, - { - "ip": "167.86.73.155", - "port": 9870 - }, - { - "ip": "167.86.73.155", - "port": 10000 - }, - { - "ip": "167.86.73.155", - "port": 40050 - }, - { - "ip": "39.105.62.172", - "port": 80 - }, - { - "ip": "39.105.62.172", - "port": 443 - }, - { - "ip": "39.105.62.172", - "port": 888 - }, - { - "ip": "39.105.62.172", - "port": 1200 - }, - { - "ip": "39.105.62.172", - "port": 2345 - }, - { - "ip": "39.105.62.172", - "port": 3000 - }, - { - "ip": "39.105.62.172", - "port": 5212 - }, - { - "ip": "39.105.62.172", - "port": 7500 - }, - { - "ip": "39.105.62.172", - "port": 8080 - }, - { - "ip": "39.105.62.172", - "port": 8081 - }, - { - "ip": "39.105.62.172", - "port": 8096 - }, - { - "ip": "39.105.62.172", - "port": 8123 - }, - { - "ip": "39.105.62.172", - "port": 9092 - }, - { - "ip": "102.221.194.195", - "port": 80 - }, - { - "ip": "102.221.194.195", - "port": 443 - }, - { - "ip": "102.221.194.195", - "port": 8080 - }, - { - "ip": "103.81.86.82", - "port": 80 - }, - { - "ip": "103.81.86.82", - "port": 443 - }, - { - "ip": "103.81.86.82", - "port": 3000 - }, - { - "ip": "103.81.86.82", - "port": 3100 - }, - { - "ip": "103.81.86.82", - "port": 8080 - }, - { - "ip": "103.81.86.82", - "port": 8282 - }, - { - "ip": "103.81.86.82", - "port": 8383 - }, - { - "ip": "219.248.14.178", - "port": 80 - }, - { - "ip": "219.248.14.178", - "port": 84 - }, - { - "ip": "219.248.14.178", - "port": 443 - }, - { - "ip": "219.248.14.178", - "port": 8080 - }, - { - "ip": "219.248.14.178", - "port": 9935 - }, - { - "ip": "222.114.144.68", - "port": 80 - }, - { - "ip": "222.114.144.68", - "port": 84 - }, - { - "ip": "222.114.144.68", - "port": 5357 - }, - { - "ip": "222.114.144.68", - "port": 6500 - }, - { - "ip": "222.114.144.68", - "port": 8080 - }, - { - "ip": "222.114.144.68", - "port": 8090 - }, - { - "ip": "3.37.236.183", - "port": 80 - }, - { - "ip": "3.37.236.183", - "port": 5000 - }, - { - "ip": "3.37.236.183", - "port": 8080 - }, - { - "ip": "18.166.216.99", - "port": 80 - }, - { - "ip": "134.249.176.139", - "port": 80 - }, - { - "ip": "134.249.176.139", - "port": 443 - }, - { - "ip": "134.249.176.139", - "port": 3000 - }, - { - "ip": "134.249.176.139", - "port": 3002 - }, - { - "ip": "134.249.176.139", - "port": 3003 - }, - { - "ip": "134.249.176.139", - "port": 3004 - }, - { - "ip": "134.249.176.139", - "port": 5357 - }, - { - "ip": "176.111.61.59", - "port": 80 - }, - { - "ip": "176.111.61.59", - "port": 443 - }, - { - "ip": "176.111.61.59", - "port": 2000 - }, - { - "ip": "176.111.61.59", - "port": 4044 - }, - { - "ip": "176.111.61.59", - "port": 5985 - }, - { - "ip": "176.111.61.59", - "port": 8080 - }, - { - "ip": "176.111.61.59", - "port": 8099 - }, - { - "ip": "176.111.61.59", - "port": 9000 - }, - { - "ip": "176.111.61.59", - "port": 9099 - }, - { - "ip": "176.111.61.59", - "port": 47001 - }, - { - "ip": "212.31.253.25", - "port": 80 - }, - { - "ip": "212.31.253.25", - "port": 443 - }, - { - "ip": "212.31.253.25", - "port": 8080 - }, - { - "ip": "217.25.94.184", - "port": 3000 - }, - { - "ip": "217.25.94.184", - "port": 3100 - }, - { - "ip": "217.25.94.184", - "port": 8090 - }, - { - "ip": "3.140.99.124", - "port": 8080 - }, - { - "ip": "106.255.230.226", - "port": 80 - }, - { - "ip": "106.255.230.226", - "port": 81 - }, - { - "ip": "106.255.230.226", - "port": 84 - }, - { - "ip": "106.255.230.226", - "port": 443 - }, - { - "ip": "106.255.230.226", - "port": 8080 - }, - { - "ip": "106.255.230.226", - "port": 9935 - }, - { - "ip": "149.56.16.187", - "port": 80 - }, - { - "ip": "149.56.16.187", - "port": 443 - }, - { - "ip": "149.56.16.187", - "port": 3002 - }, - { - "ip": "149.56.16.187", - "port": 3030 - }, - { - "ip": "149.56.16.187", - "port": 6543 - }, - { - "ip": "149.56.16.187", - "port": 9100 - }, - { - "ip": "183.98.194.131", - "port": 84 - }, - { - "ip": "183.98.194.131", - "port": 8080 - }, - { - "ip": "183.98.194.131", - "port": 9935 - }, - { - "ip": "18.232.216.49", - "port": 80 - }, - { - "ip": "34.168.166.210", - "port": 5457 - }, - { - "ip": "34.168.166.210", - "port": 5585 - }, - { - "ip": "34.168.166.210", - "port": 5589 - }, - { - "ip": "34.168.166.210", - "port": 5664 - }, - { - "ip": "34.168.166.210", - "port": 5701 - }, - { - "ip": "34.168.166.210", - "port": 5869 - }, - { - "ip": "34.168.166.210", - "port": 5901 - }, - { - "ip": "34.168.166.210", - "port": 5902 - }, - { - "ip": "34.168.166.210", - "port": 5915 - }, - { - "ip": "34.168.166.210", - "port": 5938 - }, - { - "ip": "34.168.166.210", - "port": 5984 - }, - { - "ip": "34.168.166.210", - "port": 6011 - }, - { - "ip": "34.168.166.210", - "port": 6059 - }, - { - "ip": "34.168.166.210", - "port": 6068 - }, - { - "ip": "34.168.166.210", - "port": 6166 - }, - { - "ip": "34.168.166.210", - "port": 6233 - }, - { - "ip": "34.168.166.210", - "port": 6400 - }, - { - "ip": "34.168.166.210", - "port": 6442 - }, - { - "ip": "34.168.166.210", - "port": 6458 - }, - { - "ip": "34.168.166.210", - "port": 6480 - }, - { - "ip": "34.168.166.210", - "port": 6495 - }, - { - "ip": "34.168.166.210", - "port": 6512 - }, - { - "ip": "34.168.166.210", - "port": 6522 - }, - { - "ip": "34.168.166.210", - "port": 6538 - }, - { - "ip": "34.168.166.210", - "port": 6592 - }, - { - "ip": "34.168.166.210", - "port": 6642 - }, - { - "ip": "34.168.166.210", - "port": 6661 - }, - { - "ip": "34.168.166.210", - "port": 6662 - }, - { - "ip": "34.168.166.210", - "port": 6667 - }, - { - "ip": "34.168.166.210", - "port": 6975 - }, - { - "ip": "34.168.166.210", - "port": 6980 - }, - { - "ip": "34.168.166.210", - "port": 7106 - }, - { - "ip": "34.168.166.210", - "port": 7171 - }, - { - "ip": "34.168.166.210", - "port": 7173 - }, - { - "ip": "34.168.166.210", - "port": 7180 - }, - { - "ip": "34.168.166.210", - "port": 7235 - }, - { - "ip": "34.168.166.210", - "port": 7351 - }, - { - "ip": "34.168.166.210", - "port": 7373 - }, - { - "ip": "34.168.166.210", - "port": 7453 - }, - { - "ip": "34.168.166.210", - "port": 7511 - }, - { - "ip": "34.168.166.210", - "port": 7608 - }, - { - "ip": "34.168.166.210", - "port": 7666 - }, - { - "ip": "34.168.166.210", - "port": 7687 - }, - { - "ip": "34.168.166.210", - "port": 7771 - }, - { - "ip": "34.168.166.210", - "port": 7778 - }, - { - "ip": "34.168.166.210", - "port": 7790 - }, - { - "ip": "34.168.166.210", - "port": 7885 - }, - { - "ip": "34.168.166.210", - "port": 8026 - }, - { - "ip": "34.168.166.210", - "port": 8049 - }, - { - "ip": "34.168.166.210", - "port": 8064 - }, - { - "ip": "34.168.166.210", - "port": 8068 - }, - { - "ip": "34.168.166.210", - "port": 8078 - }, - { - "ip": "52.205.199.85", - "port": 80 - }, - { - "ip": "52.205.199.85", - "port": 443 - }, - { - "ip": "52.205.199.85", - "port": 8080 - }, - { - "ip": "62.240.159.92", - "port": 80 - }, - { - "ip": "62.240.159.92", - "port": 81 - }, - { - "ip": "62.240.159.92", - "port": 443 - }, - { - "ip": "62.240.159.92", - "port": 7090 - }, - { - "ip": "62.240.159.92", - "port": 7092 - }, - { - "ip": "90.190.104.6", - "port": 80 - }, - { - "ip": "90.190.104.6", - "port": 252 - }, - { - "ip": "90.190.104.6", - "port": 443 - }, - { - "ip": "90.190.104.6", - "port": 1234 - }, - { - "ip": "90.190.104.6", - "port": 5357 - }, - { - "ip": "90.190.104.6", - "port": 7070 - }, - { - "ip": "90.190.104.6", - "port": 7071 - }, - { - "ip": "90.190.104.6", - "port": 7080 - }, - { - "ip": "90.190.104.6", - "port": 7081 - }, - { - "ip": "90.190.104.6", - "port": 8080 - }, - { - "ip": "90.190.104.6", - "port": 8090 - }, - { - "ip": "90.190.104.6", - "port": 9010 - }, - { - "ip": "90.190.104.6", - "port": 9050 - }, - { - "ip": "90.190.104.6", - "port": 9090 - }, - { - "ip": "90.190.104.6", - "port": 10000 - }, - { - "ip": "112.216.171.234", - "port": 80 - }, - { - "ip": "112.216.171.234", - "port": 84 - }, - { - "ip": "112.216.171.234", - "port": 8080 - }, - { - "ip": "112.216.171.234", - "port": 9935 - }, - { - "ip": "147.182.237.188", - "port": 80 - }, - { - "ip": "147.182.237.188", - "port": 443 - }, - { - "ip": "147.182.237.188", - "port": 1111 - }, - { - "ip": "147.182.237.188", - "port": 3333 - }, - { - "ip": "147.182.237.188", - "port": 4000 - }, - { - "ip": "147.182.237.188", - "port": 8001 - }, - { - "ip": "185.244.193.185", - "port": 80 - }, - { - "ip": "185.244.193.185", - "port": 443 - }, - { - "ip": "185.244.193.185", - "port": 8900 - }, - { - "ip": "185.244.193.185", - "port": 42069 - }, - { - "ip": "220.78.210.112", - "port": 81 - }, - { - "ip": "220.78.210.112", - "port": 84 - }, - { - "ip": "220.78.210.112", - "port": 443 - }, - { - "ip": "220.78.210.112", - "port": 8080 - }, - { - "ip": "220.78.210.112", - "port": 9935 - }, - { - "ip": "35.167.179.30", - "port": 80 - }, - { - "ip": "35.167.179.30", - "port": 443 - }, - { - "ip": "2A01:04FF:00F0:D09D:0000:0000:0000:0001", - "port": 80 - }, - { - "ip": "14.132.220.230", - "port": 80 - }, - { - "ip": "14.132.220.230", - "port": 8080 - }, - { - "ip": "54.149.237.145", - "port": 5000 - }, - { - "ip": "134.122.81.47", - "port": 80 - }, - { - "ip": "149.28.198.219", - "port": 80 - }, - { - "ip": "149.28.198.219", - "port": 443 - }, - { - "ip": "149.28.198.219", - "port": 4001 - }, - { - "ip": "149.28.198.219", - "port": 6001 - }, - { - "ip": "149.28.198.219", - "port": 6002 - }, - { - "ip": "149.28.198.219", - "port": 6100 - }, - { - "ip": "149.28.198.219", - "port": 9000 - }, - { - "ip": "175.200.165.80", - "port": 80 - }, - { - "ip": "175.200.165.80", - "port": 84 - }, - { - "ip": "175.200.165.80", - "port": 8080 - }, - { - "ip": "175.200.165.80", - "port": 9935 - }, - { - "ip": "211.217.209.151", - "port": 80 - }, - { - "ip": "211.217.209.151", - "port": 84 - }, - { - "ip": "211.217.209.151", - "port": 8080 - }, - { - "ip": "211.217.209.151", - "port": 9935 - }, - { - "ip": "46.243.205.122", - "port": 80 - }, - { - "ip": "46.243.205.122", - "port": 443 - }, - { - "ip": "46.243.205.122", - "port": 4000 - }, - { - "ip": "46.243.205.122", - "port": 4443 - }, - { - "ip": "46.243.205.122", - "port": 5000 - }, - { - "ip": "46.243.205.122", - "port": 7000 - }, - { - "ip": "46.243.205.122", - "port": 8080 - }, - { - "ip": "46.243.205.122", - "port": 8081 - }, - { - "ip": "46.243.205.122", - "port": 8989 - }, - { - "ip": "46.243.205.122", - "port": 9090 - }, - { - "ip": "188.72.108.241", - "port": 80 - }, - { - "ip": "188.72.108.241", - "port": 443 - }, - { - "ip": "188.72.108.241", - "port": 4000 - }, - { - "ip": "188.72.108.241", - "port": 4443 - }, - { - "ip": "188.72.108.241", - "port": 5000 - }, - { - "ip": "188.72.108.241", - "port": 7000 - }, - { - "ip": "188.72.108.241", - "port": 8080 - }, - { - "ip": "188.72.108.241", - "port": 8081 - }, - { - "ip": "188.72.108.241", - "port": 8989 - }, - { - "ip": "188.72.108.241", - "port": 9090 - }, - { - "ip": "45.132.240.87", - "port": 80 - }, - { - "ip": "45.132.240.87", - "port": 4000 - }, - { - "ip": "45.132.240.87", - "port": 8080 - }, - { - "ip": "45.132.240.87", - "port": 8082 - }, - { - "ip": "45.132.240.87", - "port": 8888 - }, - { - "ip": "61.74.185.166", - "port": 80 - }, - { - "ip": "61.74.185.166", - "port": 84 - }, - { - "ip": "61.74.185.166", - "port": 8080 - }, - { - "ip": "61.74.185.166", - "port": 9935 - }, - { - "ip": "191.235.99.58", - "port": 80 - }, - { - "ip": "191.235.99.58", - "port": 50002 - }, - { - "ip": "221.148.146.146", - "port": 80 - }, - { - "ip": "221.148.146.146", - "port": 84 - }, - { - "ip": "221.148.146.146", - "port": 8080 - }, - { - "ip": "221.148.146.146", - "port": 9935 - }, - { - "ip": "3.131.149.214", - "port": 80 - }, - { - "ip": "3.131.149.214", - "port": 443 - }, - { - "ip": "3.131.149.214", - "port": 8000 - }, - { - "ip": "3.131.149.214", - "port": 8008 - }, - { - "ip": "3.131.149.214", - "port": 8012 - }, - { - "ip": "3.131.149.214", - "port": 8016 - }, - { - "ip": "3.131.149.214", - "port": 8017 - }, - { - "ip": "3.131.149.214", - "port": 8019 - }, - { - "ip": "3.131.149.214", - "port": 8020 - }, - { - "ip": "3.131.149.214", - "port": 8025 - }, - { - "ip": "3.131.149.214", - "port": 8027 - }, - { - "ip": "3.131.149.214", - "port": 8080 - }, - { - "ip": "3.135.176.84", - "port": 80 - }, - { - "ip": "34.244.252.86", - "port": 8080 - }, - { - "ip": "80.211.207.17", - "port": 80 - }, - { - "ip": "80.211.207.17", - "port": 443 - }, - { - "ip": "80.211.207.17", - "port": 3001 - }, - { - "ip": "80.211.207.17", - "port": 3838 - }, - { - "ip": "80.211.207.17", - "port": 9876 - }, - { - "ip": "80.211.207.17", - "port": 16124 - }, - { - "ip": "83.96.244.108", - "port": 80 - }, - { - "ip": "83.96.244.108", - "port": 443 - }, - { - "ip": "83.96.244.108", - "port": 8888 - }, - { - "ip": "138.2.43.72", - "port": 80 - }, - { - "ip": "138.2.43.72", - "port": 443 - }, - { - "ip": "138.2.43.72", - "port": 2222 - }, - { - "ip": "138.2.43.72", - "port": 8181 - }, - { - "ip": "138.2.43.72", - "port": 38080 - }, - { - "ip": "161.97.135.20", - "port": 80 - }, - { - "ip": "161.97.135.20", - "port": 443 - }, - { - "ip": "161.97.135.20", - "port": 3000 - }, - { - "ip": "161.97.135.20", - "port": 8083 - }, - { - "ip": "161.97.135.20", - "port": 8881 - }, - { - "ip": "161.97.135.20", - "port": 33165 - }, - { - "ip": "162.243.32.41", - "port": 5005 - }, - { - "ip": "162.243.32.41", - "port": 5500 - }, - { - "ip": "162.243.32.41", - "port": 8080 - }, - { - "ip": "5.161.53.162", - "port": 80 - }, - { - "ip": "5.161.53.162", - "port": 5000 - }, - { - "ip": "13.126.73.4", - "port": 80 - }, - { - "ip": "13.213.61.130", - "port": 443 - }, - { - "ip": "13.213.61.130", - "port": 3000 - }, - { - "ip": "13.213.61.130", - "port": 3100 - }, - { - "ip": "13.213.61.130", - "port": 3101 - }, - { - "ip": "13.213.61.130", - "port": 3102 - }, - { - "ip": "13.213.61.130", - "port": 8090 - }, - { - "ip": "34.138.82.74", - "port": 80 - }, - { - "ip": "34.138.82.74", - "port": 8080 - }, - { - "ip": "34.138.82.74", - "port": 8081 - }, - { - "ip": "54.212.132.129", - "port": 80 - }, - { - "ip": "139.99.39.200", - "port": 80 - }, - { - "ip": "139.99.39.200", - "port": 443 - }, - { - "ip": "139.99.39.200", - "port": 916 - }, - { - "ip": "139.99.39.200", - "port": 943 - }, - { - "ip": "139.99.39.200", - "port": 1194 - }, - { - "ip": "139.99.39.200", - "port": 8080 - }, - { - "ip": "218.148.124.1", - "port": 80 - }, - { - "ip": "218.148.124.1", - "port": 84 - }, - { - "ip": "218.148.124.1", - "port": 6500 - }, - { - "ip": "218.148.124.1", - "port": 8080 - }, - { - "ip": "218.148.124.1", - "port": 8090 - }, - { - "ip": "37.152.190.132", - "port": 80 - }, - { - "ip": "37.152.190.132", - "port": 443 - }, - { - "ip": "37.152.190.132", - "port": 9998 - }, - { - "ip": "3.94.195.219", - "port": 80 - }, - { - "ip": "106.253.67.210", - "port": 5050 - }, - { - "ip": "106.253.67.210", - "port": 8080 - }, - { - "ip": "106.253.67.210", - "port": 8088 - }, - { - "ip": "106.253.67.210", - "port": 9935 - }, - { - "ip": "112.216.23.74", - "port": 84 - }, - { - "ip": "112.216.23.74", - "port": 8080 - }, - { - "ip": "112.216.23.74", - "port": 9935 - }, - { - "ip": "159.223.101.230", - "port": 80 - }, - { - "ip": "159.223.101.230", - "port": 443 - }, - { - "ip": "159.223.101.230", - "port": 3331 - }, - { - "ip": "174.138.123.28", - "port": 80 - }, - { - "ip": "174.138.123.28", - "port": 443 - }, - { - "ip": "174.138.123.28", - "port": 5005 - }, - { - "ip": "174.138.123.28", - "port": 8002 - }, - { - "ip": "174.138.123.28", - "port": 8084 - }, - { - "ip": "174.138.123.28", - "port": 8581 - }, - { - "ip": "174.138.123.28", - "port": 9098 - }, - { - "ip": "3.20.37.50", - "port": 80 - }, - { - "ip": "3.20.37.50", - "port": 8082 - }, - { - "ip": "13.48.103.205", - "port": 80 - }, - { - "ip": "88.99.14.150", - "port": 80 - }, - { - "ip": "88.99.14.150", - "port": 443 - }, - { - "ip": "88.99.14.150", - "port": 8080 - }, - { - "ip": "88.99.14.150", - "port": 8081 - }, - { - "ip": "96.43.94.91", - "port": 8980 - }, - { - "ip": "96.43.94.91", - "port": 10004 - }, - { - "ip": "96.43.94.91", - "port": 10009 - }, - { - "ip": "96.43.94.91", - "port": 10010 - }, - { - "ip": "96.43.94.91", - "port": 10012 - }, - { - "ip": "96.43.94.91", - "port": 10015 - }, - { - "ip": "96.43.94.91", - "port": 10016 - }, - { - "ip": "96.43.94.91", - "port": 10021 - }, - { - "ip": "96.43.94.91", - "port": 10022 - }, - { - "ip": "96.43.94.91", - "port": 10025 - }, - { - "ip": "96.43.94.91", - "port": 10044 - }, - { - "ip": "96.43.94.91", - "port": 10050 - }, - { - "ip": "96.43.94.91", - "port": 10051 - }, - { - "ip": "96.43.94.91", - "port": 20040 - }, - { - "ip": "96.43.94.91", - "port": 20043 - }, - { - "ip": "103.16.134.27", - "port": 80 - }, - { - "ip": "103.16.134.27", - "port": 443 - }, - { - "ip": "103.16.134.27", - "port": 636 - }, - { - "ip": "103.16.134.27", - "port": 8077 - }, - { - "ip": "103.16.134.27", - "port": 8080 - }, - { - "ip": "103.16.134.27", - "port": 8443 - }, - { - "ip": "103.16.134.27", - "port": 9195 - }, - { - "ip": "103.16.134.27", - "port": 23000 - }, - { - "ip": "103.16.134.27", - "port": 28880 - }, - { - "ip": "185.68.21.132", - "port": 8080 - }, - { - "ip": "199.247.9.157", - "port": 80 - }, - { - "ip": "199.247.9.157", - "port": 443 - }, - { - "ip": "199.247.9.157", - "port": 3000 - }, - { - "ip": "199.247.9.157", - "port": 3008 - }, - { - "ip": "199.247.9.157", - "port": 3009 - }, - { - "ip": "199.247.9.157", - "port": 5000 - }, - { - "ip": "199.247.9.157", - "port": 8080 - }, - { - "ip": "35.247.197.40", - "port": 80 - }, - { - "ip": "35.247.197.40", - "port": 8080 - }, - { - "ip": "35.247.197.40", - "port": 8081 - }, - { - "ip": "51.11.153.220", - "port": 3000 - }, - { - "ip": "51.11.153.220", - "port": 3333 - }, - { - "ip": "51.11.153.220", - "port": 5000 - }, - { - "ip": "51.11.153.220", - "port": 5001 - }, - { - "ip": "51.11.153.220", - "port": 8080 - }, - { - "ip": "51.11.153.220", - "port": 8081 - }, - { - "ip": "51.11.153.220", - "port": 19999 - }, - { - "ip": "170.178.220.221", - "port": 80 - }, - { - "ip": "185.229.226.141", - "port": 3001 - }, - { - "ip": "185.229.226.141", - "port": 8080 - }, - { - "ip": "5.135.183.154", - "port": 80 - }, - { - "ip": "5.135.183.154", - "port": 443 - }, - { - "ip": "5.135.183.154", - "port": 3000 - }, - { - "ip": "5.135.183.154", - "port": 8181 - }, - { - "ip": "5.135.183.154", - "port": 8182 - }, - { - "ip": "5.135.183.154", - "port": 9600 - }, - { - "ip": "5.135.183.154", - "port": 39999 - }, - { - "ip": "18.215.167.22", - "port": 80 - }, - { - "ip": "34.31.41.121", - "port": 8089 - }, - { - "ip": "167.172.151.242", - "port": 80 - }, - { - "ip": "167.172.151.242", - "port": 443 - }, - { - "ip": "167.172.151.242", - "port": 3000 - }, - { - "ip": "167.172.151.242", - "port": 8080 - }, - { - "ip": "167.172.151.242", - "port": 8081 - }, - { - "ip": "175.208.170.55", - "port": 80 - }, - { - "ip": "175.208.170.55", - "port": 84 - }, - { - "ip": "175.208.170.55", - "port": 8080 - }, - { - "ip": "175.208.170.55", - "port": 9935 - }, - { - "ip": "202.61.199.8", - "port": 80 - }, - { - "ip": "202.61.199.8", - "port": 443 - }, - { - "ip": "202.61.199.8", - "port": 8080 - }, - { - "ip": "202.61.199.8", - "port": 8443 - }, - { - "ip": "202.61.199.8", - "port": 8614 - }, - { - "ip": "202.61.199.8", - "port": 8880 - }, - { - "ip": "202.61.199.8", - "port": 9000 - }, - { - "ip": "39.120.227.14", - "port": 80 - }, - { - "ip": "39.120.227.14", - "port": 84 - }, - { - "ip": "39.120.227.14", - "port": 8080 - }, - { - "ip": "39.120.227.14", - "port": 9935 - }, - { - "ip": "128.199.34.91", - "port": 443 - }, - { - "ip": "128.199.34.91", - "port": 8000 - }, - { - "ip": "128.199.34.91", - "port": 8080 - }, - { - "ip": "158.101.219.107", - "port": 80 - }, - { - "ip": "158.101.219.107", - "port": 443 - }, - { - "ip": "158.101.219.107", - "port": 8846 - }, - { - "ip": "158.101.219.107", - "port": 9440 - }, - { - "ip": "159.89.155.250", - "port": 80 - }, - { - "ip": "159.89.155.250", - "port": 443 - }, - { - "ip": "159.89.155.250", - "port": 8080 - }, - { - "ip": "3.23.100.22", - "port": 80 - }, - { - "ip": "3.23.100.22", - "port": 3001 - }, - { - "ip": "23.88.126.94", - "port": 80 - }, - { - "ip": "23.88.126.94", - "port": 443 - }, - { - "ip": "23.88.126.94", - "port": 8080 - }, - { - "ip": "35.180.184.133", - "port": 80 - }, - { - "ip": "121.189.75.120", - "port": 80 - }, - { - "ip": "121.189.75.120", - "port": 84 - }, - { - "ip": "121.189.75.120", - "port": 8080 - }, - { - "ip": "121.189.75.120", - "port": 8090 - }, - { - "ip": "121.189.75.120", - "port": 9935 - }, - { - "ip": "158.255.74.5", - "port": 5357 - }, - { - "ip": "158.255.74.5", - "port": 5985 - }, - { - "ip": "158.255.74.5", - "port": 5986 - }, - { - "ip": "158.255.74.5", - "port": 8080 - }, - { - "ip": "158.255.74.5", - "port": 47001 - }, - { - "ip": "191.185.163.152", - "port": 8085 - }, - { - "ip": "191.185.163.152", - "port": 8091 - }, - { - "ip": "191.185.163.152", - "port": 8098 - }, - { - "ip": "191.185.163.152", - "port": 8099 - }, - { - "ip": "191.185.163.152", - "port": 8888 - }, - { - "ip": "213.136.92.239", - "port": 80 - }, - { - "ip": "213.136.92.239", - "port": 443 - }, - { - "ip": "213.136.92.239", - "port": 3000 - }, - { - "ip": "213.136.92.239", - "port": 8080 - }, - { - "ip": "34.89.42.44", - "port": 5014 - }, - { - "ip": "34.89.42.44", - "port": 5017 - }, - { - "ip": "45.10.26.50", - "port": 80 - }, - { - "ip": "45.10.26.50", - "port": 443 - }, - { - "ip": "45.10.26.50", - "port": 7050 - }, - { - "ip": "45.10.26.50", - "port": 7080 - }, - { - "ip": "45.10.26.50", - "port": 7081 - }, - { - "ip": "45.10.26.50", - "port": 8006 - }, - { - "ip": "45.10.26.50", - "port": 8443 - }, - { - "ip": "45.10.26.50", - "port": 8880 - }, - { - "ip": "51.79.72.71", - "port": 80 - }, - { - "ip": "51.79.72.71", - "port": 81 - }, - { - "ip": "51.79.72.71", - "port": 443 - }, - { - "ip": "51.79.72.71", - "port": 4000 - }, - { - "ip": "51.79.72.71", - "port": 4040 - }, - { - "ip": "51.79.72.71", - "port": 4041 - }, - { - "ip": "51.79.72.71", - "port": 6543 - }, - { - "ip": "51.79.72.71", - "port": 9100 - }, - { - "ip": "51.79.72.71", - "port": 9256 - }, - { - "ip": "51.79.72.71", - "port": 15672 - }, - { - "ip": "121.40.73.144", - "port": 80 - }, - { - "ip": "121.40.73.144", - "port": 443 - }, - { - "ip": "121.40.73.144", - "port": 888 - }, - { - "ip": "121.40.73.144", - "port": 1200 - }, - { - "ip": "121.40.73.144", - "port": 5244 - }, - { - "ip": "121.40.73.144", - "port": 8008 - }, - { - "ip": "121.40.73.144", - "port": 8080 - }, - { - "ip": "121.40.73.144", - "port": 8888 - }, - { - "ip": "129.153.193.186", - "port": 80 - }, - { - "ip": "129.153.193.186", - "port": 443 - }, - { - "ip": "129.153.193.186", - "port": 3000 - }, - { - "ip": "129.153.193.186", - "port": 3001 - }, - { - "ip": "167.99.48.199", - "port": 80 - }, - { - "ip": "167.99.48.199", - "port": 443 - }, - { - "ip": "167.99.48.199", - "port": 8080 - }, - { - "ip": "175.213.189.48", - "port": 80 - }, - { - "ip": "175.213.189.48", - "port": 84 - }, - { - "ip": "175.213.189.48", - "port": 6500 - }, - { - "ip": "175.213.189.48", - "port": 8080 - }, - { - "ip": "175.213.189.48", - "port": 8090 - }, - { - "ip": "200.91.201.186", - "port": 80 - }, - { - "ip": "200.91.201.186", - "port": 91 - }, - { - "ip": "200.91.201.186", - "port": 443 - }, - { - "ip": "200.91.201.186", - "port": 8001 - }, - { - "ip": "200.91.201.186", - "port": 8002 - }, - { - "ip": "200.91.201.186", - "port": 8080 - }, - { - "ip": "200.91.201.186", - "port": 8090 - }, - { - "ip": "200.91.201.186", - "port": 8383 - }, - { - "ip": "200.91.201.186", - "port": 9191 - }, - { - "ip": "200.91.201.186", - "port": 12000 - }, - { - "ip": "200.91.201.186", - "port": 12001 - }, - { - "ip": "200.155.185.180", - "port": 9999 - }, - { - "ip": "221.4.156.74", - "port": 82 - }, - { - "ip": "221.4.156.74", - "port": 3159 - }, - { - "ip": "221.4.156.74", - "port": 6002 - }, - { - "ip": "221.4.156.74", - "port": 7003 - }, - { - "ip": "221.4.156.74", - "port": 8061 - }, - { - "ip": "221.4.156.74", - "port": 8062 - }, - { - "ip": "221.4.156.74", - "port": 8064 - }, - { - "ip": "221.4.156.74", - "port": 8066 - }, - { - "ip": "221.4.156.74", - "port": 8074 - }, - { - "ip": "221.4.156.74", - "port": 8081 - }, - { - "ip": "221.4.156.74", - "port": 8082 - }, - { - "ip": "221.4.156.74", - "port": 8083 - }, - { - "ip": "221.4.156.74", - "port": 8084 - }, - { - "ip": "221.4.156.74", - "port": 8085 - }, - { - "ip": "221.4.156.74", - "port": 8161 - }, - { - "ip": "221.4.156.74", - "port": 8184 - }, - { - "ip": "221.4.156.74", - "port": 8235 - }, - { - "ip": "221.4.156.74", - "port": 8280 - }, - { - "ip": "221.4.156.74", - "port": 8282 - }, - { - "ip": "221.4.156.74", - "port": 8486 - }, - { - "ip": "221.4.156.74", - "port": 8585 - }, - { - "ip": "221.4.156.74", - "port": 8586 - }, - { - "ip": "221.4.156.74", - "port": 8882 - }, - { - "ip": "221.4.156.74", - "port": 9066 - }, - { - "ip": "221.4.156.74", - "port": 9085 - }, - { - "ip": "221.4.156.74", - "port": 9090 - }, - { - "ip": "221.4.156.74", - "port": 9901 - }, - { - "ip": "221.4.156.74", - "port": 10200 - }, - { - "ip": "221.4.156.74", - "port": 20500 - }, - { - "ip": "44.229.65.15", - "port": 80 - }, - { - "ip": "44.229.65.15", - "port": 443 - }, - { - "ip": "99.80.66.49", - "port": 443 - }, - { - "ip": "99.80.66.49", - "port": 8443 - }, - { - "ip": "99.80.66.49", - "port": 8444 - }, - { - "ip": "120.24.58.145", - "port": 80 - }, - { - "ip": "120.24.58.145", - "port": 443 - }, - { - "ip": "120.24.58.145", - "port": 8081 - }, - { - "ip": "120.24.58.145", - "port": 8090 - }, - { - "ip": "120.24.58.145", - "port": 8118 - }, - { - "ip": "120.24.58.145", - "port": 8443 - }, - { - "ip": "120.24.58.145", - "port": 9001 - }, - { - "ip": "3.38.240.108", - "port": 80 - }, - { - "ip": "8.210.217.1", - "port": 80 - }, - { - "ip": "8.210.217.1", - "port": 443 - }, - { - "ip": "8.210.217.1", - "port": 8080 - }, - { - "ip": "8.210.217.1", - "port": 8888 - }, - { - "ip": "34.195.152.253", - "port": 80 - }, - { - "ip": "49.255.68.39", - "port": 80 - }, - { - "ip": "49.255.68.39", - "port": 443 - }, - { - "ip": "49.255.68.39", - "port": 5000 - }, - { - "ip": "49.255.68.39", - "port": 8080 - }, - { - "ip": "49.255.68.39", - "port": 39393 - }, - { - "ip": "121.141.26.194", - "port": 80 - }, - { - "ip": "121.141.26.194", - "port": 84 - }, - { - "ip": "121.141.26.194", - "port": 443 - }, - { - "ip": "121.141.26.194", - "port": 8080 - }, - { - "ip": "121.141.26.194", - "port": 9935 - }, - { - "ip": "167.99.102.125", - "port": 80 - }, - { - "ip": "167.99.102.125", - "port": 443 - }, - { - "ip": "167.99.102.125", - "port": 1337 - }, - { - "ip": "167.99.102.125", - "port": 2001 - }, - { - "ip": "167.99.102.125", - "port": 4000 - }, - { - "ip": "167.99.102.125", - "port": 8000 - }, - { - "ip": "167.99.102.125", - "port": 8090 - }, - { - "ip": "167.99.102.125", - "port": 8176 - }, - { - "ip": "167.99.102.125", - "port": 9091 - }, - { - "ip": "167.99.102.125", - "port": 18081 - }, - { - "ip": "167.99.102.125", - "port": 18082 - }, - { - "ip": "167.99.102.125", - "port": 18083 - }, - { - "ip": "167.99.102.125", - "port": 18463 - }, - { - "ip": "167.172.42.50", - "port": 80 - }, - { - "ip": "167.172.42.50", - "port": 443 - }, - { - "ip": "167.172.42.50", - "port": 8070 - }, - { - "ip": "167.172.42.50", - "port": 8090 - }, - { - "ip": "34.30.78.208", - "port": 8080 - }, - { - "ip": "34.30.78.208", - "port": 8090 - }, - { - "ip": "34.30.78.208", - "port": 10000 - }, - { - "ip": "18.206.36.122", - "port": 80 - }, - { - "ip": "18.206.36.122", - "port": 443 - }, - { - "ip": "51.250.18.230", - "port": 80 - }, - { - "ip": "51.250.18.230", - "port": 443 - }, - { - "ip": "51.250.18.230", - "port": 7000 - }, - { - "ip": "51.250.18.230", - "port": 7350 - }, - { - "ip": "51.250.18.230", - "port": 7500 - }, - { - "ip": "51.250.18.230", - "port": 7550 - }, - { - "ip": "51.250.18.230", - "port": 7600 - }, - { - "ip": "51.250.18.230", - "port": 8887 - }, - { - "ip": "51.250.18.230", - "port": 8888 - }, - { - "ip": "138.197.208.159", - "port": 80 - }, - { - "ip": "138.197.208.159", - "port": 443 - }, - { - "ip": "192.99.232.224", - "port": 80 - }, - { - "ip": "192.99.232.224", - "port": 443 - }, - { - "ip": "192.99.232.224", - "port": 3001 - }, - { - "ip": "192.99.232.224", - "port": 3002 - }, - { - "ip": "192.99.232.224", - "port": 3003 - }, - { - "ip": "192.99.232.224", - "port": 3004 - }, - { - "ip": "192.99.232.224", - "port": 3005 - }, - { - "ip": "192.99.232.224", - "port": 3007 - }, - { - "ip": "192.99.232.224", - "port": 3008 - }, - { - "ip": "192.99.232.224", - "port": 3009 - }, - { - "ip": "192.99.232.224", - "port": 3010 - }, - { - "ip": "192.99.232.224", - "port": 3011 - }, - { - "ip": "192.99.232.224", - "port": 3041 - }, - { - "ip": "192.99.232.224", - "port": 3042 - }, - { - "ip": "192.99.232.224", - "port": 3044 - }, - { - "ip": "192.99.232.224", - "port": 3046 - }, - { - "ip": "192.99.232.224", - "port": 3047 - }, - { - "ip": "192.99.232.224", - "port": 3050 - }, - { - "ip": "192.99.232.224", - "port": 3095 - }, - { - "ip": "192.99.232.224", - "port": 3320 - }, - { - "ip": "192.99.232.224", - "port": 3340 - }, - { - "ip": "192.99.232.224", - "port": 3567 - }, - { - "ip": "192.99.232.224", - "port": 3773 - }, - { - "ip": "192.99.232.224", - "port": 3784 - }, - { - "ip": "192.99.232.224", - "port": 4010 - }, - { - "ip": "192.99.232.224", - "port": 4881 - }, - { - "ip": "192.99.232.224", - "port": 5001 - }, - { - "ip": "192.99.232.224", - "port": 5002 - }, - { - "ip": "192.99.232.224", - "port": 5555 - }, - { - "ip": "192.99.232.224", - "port": 5656 - }, - { - "ip": "192.99.232.224", - "port": 5657 - }, - { - "ip": "192.99.232.224", - "port": 6768 - }, - { - "ip": "192.99.232.224", - "port": 7878 - }, - { - "ip": "192.99.232.224", - "port": 7979 - }, - { - "ip": "192.99.232.224", - "port": 8085 - }, - { - "ip": "192.99.232.224", - "port": 8086 - }, - { - "ip": "192.99.232.224", - "port": 8087 - }, - { - "ip": "192.99.232.224", - "port": 8088 - }, - { - "ip": "192.99.232.224", - "port": 8095 - }, - { - "ip": "192.99.232.224", - "port": 8096 - }, - { - "ip": "192.99.232.224", - "port": 8097 - }, - { - "ip": "192.99.232.224", - "port": 8099 - }, - { - "ip": "192.99.232.224", - "port": 9095 - }, - { - "ip": "192.99.232.224", - "port": 9096 - }, - { - "ip": "192.99.232.224", - "port": 59005 - }, - { - "ip": "195.154.240.190", - "port": 80 - }, - { - "ip": "195.154.240.190", - "port": 443 - }, - { - "ip": "195.154.240.190", - "port": 6666 - }, - { - "ip": "195.154.240.190", - "port": 8096 - }, - { - "ip": "195.154.240.190", - "port": 9091 - }, - { - "ip": "3.67.134.228", - "port": 8080 - }, - { - "ip": "3.134.91.166", - "port": 8080 - }, - { - "ip": "35.247.10.31", - "port": 5474 - }, - { - "ip": "35.247.10.31", - "port": 5568 - }, - { - "ip": "35.247.10.31", - "port": 5597 - }, - { - "ip": "35.247.10.31", - "port": 5784 - }, - { - "ip": "35.247.10.31", - "port": 5789 - }, - { - "ip": "35.247.10.31", - "port": 5807 - }, - { - "ip": "35.247.10.31", - "port": 5907 - }, - { - "ip": "35.247.10.31", - "port": 5913 - }, - { - "ip": "35.247.10.31", - "port": 5916 - }, - { - "ip": "35.247.10.31", - "port": 5918 - }, - { - "ip": "35.247.10.31", - "port": 6011 - }, - { - "ip": "35.247.10.31", - "port": 6022 - }, - { - "ip": "35.247.10.31", - "port": 6030 - }, - { - "ip": "35.247.10.31", - "port": 6060 - }, - { - "ip": "35.247.10.31", - "port": 6070 - }, - { - "ip": "35.247.10.31", - "port": 6102 - }, - { - "ip": "35.247.10.31", - "port": 6114 - }, - { - "ip": "35.247.10.31", - "port": 6337 - }, - { - "ip": "35.247.10.31", - "port": 6489 - }, - { - "ip": "35.247.10.31", - "port": 6560 - }, - { - "ip": "35.247.10.31", - "port": 6580 - }, - { - "ip": "35.247.10.31", - "port": 6835 - }, - { - "ip": "35.247.10.31", - "port": 7100 - }, - { - "ip": "35.247.10.31", - "port": 7161 - }, - { - "ip": "35.247.10.31", - "port": 7170 - }, - { - "ip": "35.247.10.31", - "port": 7373 - }, - { - "ip": "35.247.10.31", - "port": 7406 - }, - { - "ip": "35.247.10.31", - "port": 7480 - }, - { - "ip": "35.247.10.31", - "port": 7623 - }, - { - "ip": "35.247.10.31", - "port": 7654 - }, - { - "ip": "35.247.10.31", - "port": 7778 - }, - { - "ip": "35.247.10.31", - "port": 7779 - }, - { - "ip": "35.247.10.31", - "port": 7955 - }, - { - "ip": "35.247.10.31", - "port": 8010 - }, - { - "ip": "35.247.10.31", - "port": 8012 - }, - { - "ip": "35.247.10.31", - "port": 8053 - }, - { - "ip": "54.209.87.95", - "port": 8080 - }, - { - "ip": "95.216.162.23", - "port": 80 - }, - { - "ip": "95.216.162.23", - "port": 8080 - }, - { - "ip": "95.216.162.23", - "port": 8888 - }, - { - "ip": "106.54.59.105", - "port": 80 - }, - { - "ip": "106.54.59.105", - "port": 443 - }, - { - "ip": "106.54.59.105", - "port": 3001 - }, - { - "ip": "106.54.59.105", - "port": 7002 - }, - { - "ip": "106.54.59.105", - "port": 7500 - }, - { - "ip": "106.54.59.105", - "port": 9101 - }, - { - "ip": "106.54.59.105", - "port": 10088 - }, - { - "ip": "122.168.75.223", - "port": 8000 - }, - { - "ip": "122.168.75.223", - "port": 8080 - }, - { - "ip": "192.18.151.7", - "port": 8080 - }, - { - "ip": "52.87.80.39", - "port": 80 - }, - { - "ip": "52.87.80.39", - "port": 443 - }, - { - "ip": "104.248.240.138", - "port": 80 - }, - { - "ip": "104.248.240.138", - "port": 443 - }, - { - "ip": "104.248.240.138", - "port": 8443 - }, - { - "ip": "104.248.240.138", - "port": 8444 - }, - { - "ip": "42.116.22.215", - "port": 80 - }, - { - "ip": "42.116.22.215", - "port": 81 - }, - { - "ip": "42.116.22.215", - "port": 443 - }, - { - "ip": "42.116.22.215", - "port": 5000 - }, - { - "ip": "42.116.22.215", - "port": 5002 - }, - { - "ip": "42.116.22.215", - "port": 8080 - }, - { - "ip": "42.116.22.215", - "port": 8082 - }, - { - "ip": "42.116.22.215", - "port": 8083 - }, - { - "ip": "42.116.22.215", - "port": 8100 - }, - { - "ip": "42.116.22.215", - "port": 8887 - }, - { - "ip": "42.116.22.215", - "port": 8888 - }, - { - "ip": "51.79.133.76", - "port": 80 - }, - { - "ip": "51.79.133.76", - "port": 443 - }, - { - "ip": "51.79.133.76", - "port": 943 - }, - { - "ip": "51.79.133.76", - "port": 1194 - }, - { - "ip": "51.79.133.76", - "port": 8080 - }, - { - "ip": "89.86.114.28", - "port": 80 - }, - { - "ip": "89.86.114.28", - "port": 443 - }, - { - "ip": "89.86.114.28", - "port": 9000 - }, - { - "ip": "89.86.114.28", - "port": 10000 - }, - { - "ip": "89.86.114.28", - "port": 18001 - }, - { - "ip": "89.86.114.28", - "port": 18018 - }, - { - "ip": "89.86.114.28", - "port": 18038 - }, - { - "ip": "89.86.114.28", - "port": 18081 - }, - { - "ip": "89.86.114.28", - "port": 18888 - }, - { - "ip": "94.23.85.131", - "port": 80 - }, - { - "ip": "94.23.85.131", - "port": 443 - }, - { - "ip": "94.23.85.131", - "port": 8070 - }, - { - "ip": "94.23.85.131", - "port": 8080 - }, - { - "ip": "94.23.85.131", - "port": 8082 - }, - { - "ip": "94.23.85.131", - "port": 8090 - }, - { - "ip": "94.23.85.131", - "port": 8091 - }, - { - "ip": "121.157.165.163", - "port": 80 - }, - { - "ip": "121.157.165.163", - "port": 81 - }, - { - "ip": "121.157.165.163", - "port": 84 - }, - { - "ip": "121.157.165.163", - "port": 443 - }, - { - "ip": "121.157.165.163", - "port": 8080 - }, - { - "ip": "121.157.165.163", - "port": 9935 - }, - { - "ip": "200.49.38.250", - "port": 4433 - }, - { - "ip": "200.49.38.250", - "port": 8080 - }, - { - "ip": "200.49.38.250", - "port": 8081 - }, - { - "ip": "200.49.38.250", - "port": 8082 - }, - { - "ip": "200.49.38.250", - "port": 8084 - }, - { - "ip": "200.49.38.250", - "port": 8085 - }, - { - "ip": "200.49.38.250", - "port": 9089 - }, - { - "ip": "200.49.38.250", - "port": 9090 - }, - { - "ip": "200.49.38.250", - "port": 9091 - }, - { - "ip": "200.49.38.250", - "port": 9092 - }, - { - "ip": "200.49.38.250", - "port": 10001 - }, - { - "ip": "200.49.38.250", - "port": 43703 - }, - { - "ip": "210.124.192.12", - "port": 80 - }, - { - "ip": "210.124.192.12", - "port": 84 - }, - { - "ip": "210.124.192.12", - "port": 8080 - }, - { - "ip": "210.124.192.12", - "port": 8090 - }, - { - "ip": "13.51.45.235", - "port": 80 - }, - { - "ip": "34.217.218.199", - "port": 80 - }, - { - "ip": "34.217.218.199", - "port": 443 - }, - { - "ip": "34.217.218.199", - "port": 5000 - }, - { - "ip": "34.217.218.199", - "port": 5001 - }, - { - "ip": "34.217.218.199", - "port": 8000 - }, - { - "ip": "34.217.218.199", - "port": 8080 - }, - { - "ip": "34.217.218.199", - "port": 8090 - }, - { - "ip": "47.98.55.245", - "port": 80 - }, - { - "ip": "47.98.55.245", - "port": 443 - }, - { - "ip": "47.98.55.245", - "port": 8080 - }, - { - "ip": "47.98.55.245", - "port": 8088 - }, - { - "ip": "47.98.55.245", - "port": 8848 - }, - { - "ip": "47.98.55.245", - "port": 8990 - }, - { - "ip": "47.98.55.245", - "port": 8991 - }, - { - "ip": "47.98.55.245", - "port": 9060 - }, - { - "ip": "47.98.55.245", - "port": 9595 - }, - { - "ip": "47.98.55.245", - "port": 18848 - }, - { - "ip": "52.201.42.180", - "port": 80 - }, - { - "ip": "52.201.42.180", - "port": 8080 - }, - { - "ip": "52.201.42.180", - "port": 8081 - }, - { - "ip": "52.201.42.180", - "port": 56789 - }, - { - "ip": "58.142.73.22", - "port": 84 - }, - { - "ip": "58.142.73.22", - "port": 8080 - }, - { - "ip": "58.142.73.22", - "port": 9935 - }, - { - "ip": "211.107.18.186", - "port": 80 - }, - { - "ip": "211.107.18.186", - "port": 81 - }, - { - "ip": "211.107.18.186", - "port": 84 - }, - { - "ip": "211.107.18.186", - "port": 443 - }, - { - "ip": "211.107.18.186", - "port": 8080 - }, - { - "ip": "211.107.18.186", - "port": 9935 - }, - { - "ip": "35.176.192.182", - "port": 1234 - }, - { - "ip": "35.176.192.182", - "port": 3000 - }, - { - "ip": "35.176.192.182", - "port": 4000 - }, - { - "ip": "35.176.192.182", - "port": 8082 - }, - { - "ip": "35.176.192.182", - "port": 8083 - }, - { - "ip": "35.176.192.182", - "port": 8084 - }, - { - "ip": "35.176.192.182", - "port": 8085 - }, - { - "ip": "35.176.192.182", - "port": 8086 - }, - { - "ip": "35.176.192.182", - "port": 8087 - }, - { - "ip": "35.176.192.182", - "port": 8088 - }, - { - "ip": "35.176.192.182", - "port": 8840 - }, - { - "ip": "35.176.192.182", - "port": 8841 - }, - { - "ip": "54.194.95.48", - "port": 8080 - }, - { - "ip": "54.194.95.48", - "port": 8081 - }, - { - "ip": "54.194.95.48", - "port": 8082 - }, - { - "ip": "130.193.36.82", - "port": 80 - }, - { - "ip": "130.193.36.82", - "port": 443 - }, - { - "ip": "130.193.36.82", - "port": 7000 - }, - { - "ip": "130.193.36.82", - "port": 7300 - }, - { - "ip": "130.193.36.82", - "port": 7350 - }, - { - "ip": "130.193.36.82", - "port": 7500 - }, - { - "ip": "130.193.36.82", - "port": 7550 - }, - { - "ip": "130.193.36.82", - "port": 7600 - }, - { - "ip": "130.193.36.82", - "port": 8887 - }, - { - "ip": "130.193.36.82", - "port": 8888 - }, - { - "ip": "222.99.197.200", - "port": 81 - }, - { - "ip": "222.99.197.200", - "port": 84 - }, - { - "ip": "222.99.197.200", - "port": 443 - }, - { - "ip": "222.99.197.200", - "port": 8080 - }, - { - "ip": "222.99.197.200", - "port": 9935 - }, - { - "ip": "35.197.65.246", - "port": 5440 - }, - { - "ip": "35.197.65.246", - "port": 5524 - }, - { - "ip": "35.197.65.246", - "port": 5543 - }, - { - "ip": "35.197.65.246", - "port": 5600 - }, - { - "ip": "35.197.65.246", - "port": 5603 - }, - { - "ip": "35.197.65.246", - "port": 5620 - }, - { - "ip": "35.197.65.246", - "port": 5660 - }, - { - "ip": "35.197.65.246", - "port": 5671 - }, - { - "ip": "35.197.65.246", - "port": 5797 - }, - { - "ip": "35.197.65.246", - "port": 5840 - }, - { - "ip": "35.197.65.246", - "port": 5901 - }, - { - "ip": "35.197.65.246", - "port": 5903 - }, - { - "ip": "35.197.65.246", - "port": 5908 - }, - { - "ip": "35.197.65.246", - "port": 5996 - }, - { - "ip": "35.197.65.246", - "port": 6022 - }, - { - "ip": "35.197.65.246", - "port": 6113 - }, - { - "ip": "35.197.65.246", - "port": 6190 - }, - { - "ip": "35.197.65.246", - "port": 6298 - }, - { - "ip": "35.197.65.246", - "port": 6328 - }, - { - "ip": "35.197.65.246", - "port": 6329 - }, - { - "ip": "35.197.65.246", - "port": 6467 - }, - { - "ip": "35.197.65.246", - "port": 6560 - }, - { - "ip": "35.197.65.246", - "port": 6561 - }, - { - "ip": "35.197.65.246", - "port": 6686 - }, - { - "ip": "35.197.65.246", - "port": 6691 - }, - { - "ip": "35.197.65.246", - "port": 6916 - }, - { - "ip": "35.197.65.246", - "port": 7003 - }, - { - "ip": "35.197.65.246", - "port": 7037 - }, - { - "ip": "35.197.65.246", - "port": 7083 - }, - { - "ip": "35.197.65.246", - "port": 7139 - }, - { - "ip": "35.197.65.246", - "port": 7259 - }, - { - "ip": "35.197.65.246", - "port": 7286 - }, - { - "ip": "35.197.65.246", - "port": 7327 - }, - { - "ip": "35.197.65.246", - "port": 7373 - }, - { - "ip": "35.197.65.246", - "port": 7436 - }, - { - "ip": "35.197.65.246", - "port": 7478 - }, - { - "ip": "35.197.65.246", - "port": 7585 - }, - { - "ip": "35.197.65.246", - "port": 7777 - }, - { - "ip": "35.197.65.246", - "port": 7998 - }, - { - "ip": "35.197.65.246", - "port": 8001 - }, - { - "ip": "35.197.65.246", - "port": 8014 - }, - { - "ip": "35.197.65.246", - "port": 8048 - }, - { - "ip": "35.197.65.246", - "port": 8053 - }, - { - "ip": "35.197.65.246", - "port": 8075 - }, - { - "ip": "54.217.162.158", - "port": 80 - }, - { - "ip": "106.248.19.11", - "port": 80 - }, - { - "ip": "106.248.19.11", - "port": 84 - }, - { - "ip": "106.248.19.11", - "port": 8080 - }, - { - "ip": "121.163.198.167", - "port": 84 - }, - { - "ip": "121.163.198.167", - "port": 8080 - }, - { - "ip": "165.22.245.105", - "port": 80 - }, - { - "ip": "165.22.245.105", - "port": 443 - }, - { - "ip": "165.22.245.105", - "port": 3456 - }, - { - "ip": "165.22.245.105", - "port": 3838 - }, - { - "ip": "165.22.245.105", - "port": 8058 - }, - { - "ip": "165.22.245.105", - "port": 9058 - }, - { - "ip": "165.22.245.105", - "port": 9158 - }, - { - "ip": "185.227.108.62", - "port": 80 - }, - { - "ip": "185.227.108.62", - "port": 443 - }, - { - "ip": "185.227.108.62", - "port": 4194 - }, - { - "ip": "185.227.108.62", - "port": 8008 - }, - { - "ip": "185.227.108.62", - "port": 8085 - }, - { - "ip": "185.227.108.62", - "port": 8161 - }, - { - "ip": "185.227.108.62", - "port": 9100 - }, - { - "ip": "185.227.108.62", - "port": 9999 - }, - { - "ip": "3.138.186.181", - "port": 80 - }, - { - "ip": "3.138.186.181", - "port": 4000 - }, - { - "ip": "3.138.186.181", - "port": 8080 - }, - { - "ip": "34.207.251.127", - "port": 80 - }, - { - "ip": "63.35.178.37", - "port": 80 - }, - { - "ip": "63.35.178.37", - "port": 443 - }, - { - "ip": "63.35.178.37", - "port": 8080 - }, - { - "ip": "64.227.99.110", - "port": 80 - }, - { - "ip": "104.248.209.146", - "port": 80 - }, - { - "ip": "104.248.209.146", - "port": 443 - }, - { - "ip": "104.248.209.146", - "port": 2000 - }, - { - "ip": "104.248.209.146", - "port": 3000 - }, - { - "ip": "119.204.186.16", - "port": 80 - }, - { - "ip": "119.204.186.16", - "port": 84 - }, - { - "ip": "119.204.186.16", - "port": 8080 - }, - { - "ip": "119.204.186.16", - "port": 9935 - }, - { - "ip": "146.185.145.20", - "port": 80 - }, - { - "ip": "146.185.145.20", - "port": 443 - }, - { - "ip": "146.185.145.20", - "port": 8080 - }, - { - "ip": "174.138.107.78", - "port": 80 - }, - { - "ip": "174.138.107.78", - "port": 443 - }, - { - "ip": "174.138.107.78", - "port": 1000 - }, - { - "ip": "174.138.107.78", - "port": 1005 - }, - { - "ip": "174.138.107.78", - "port": 1040 - }, - { - "ip": "174.138.107.78", - "port": 1050 - }, - { - "ip": "174.138.107.78", - "port": 1055 - }, - { - "ip": "174.138.107.78", - "port": 9001 - }, - { - "ip": "174.138.107.78", - "port": 49153 - }, - { - "ip": "85.215.165.64", - "port": 81 - }, - { - "ip": "85.215.165.64", - "port": 5000 - }, - { - "ip": "121.174.67.90", - "port": 80 - }, - { - "ip": "121.174.67.90", - "port": 84 - }, - { - "ip": "121.174.67.90", - "port": 8080 - }, - { - "ip": "121.174.67.90", - "port": 9935 - }, - { - "ip": "163.172.4.169", - "port": 80 - }, - { - "ip": "163.172.4.169", - "port": 443 - }, - { - "ip": "163.172.4.169", - "port": 2000 - }, - { - "ip": "163.172.4.169", - "port": 3000 - }, - { - "ip": "163.172.4.169", - "port": 3200 - }, - { - "ip": "163.172.4.169", - "port": 3567 - }, - { - "ip": "163.172.4.169", - "port": 4000 - }, - { - "ip": "163.172.4.169", - "port": 7002 - }, - { - "ip": "163.172.4.169", - "port": 7003 - }, - { - "ip": "163.172.4.169", - "port": 8001 - }, - { - "ip": "163.172.4.169", - "port": 8002 - }, - { - "ip": "163.172.4.169", - "port": 8010 - }, - { - "ip": "163.172.4.169", - "port": 8080 - }, - { - "ip": "163.172.4.169", - "port": 8082 - }, - { - "ip": "163.172.4.169", - "port": 8083 - }, - { - "ip": "163.172.4.169", - "port": 8084 - }, - { - "ip": "163.172.4.169", - "port": 9901 - }, - { - "ip": "13.229.41.166", - "port": 80 - }, - { - "ip": "13.229.41.166", - "port": 443 - }, - { - "ip": "3.13.149.88", - "port": 80 - }, - { - "ip": "3.13.149.88", - "port": 443 - }, - { - "ip": "3.13.149.88", - "port": 3000 - }, - { - "ip": "3.13.149.88", - "port": 8050 - }, - { - "ip": "3.13.149.88", - "port": 8081 - }, - { - "ip": "3.211.245.210", - "port": 80 - }, - { - "ip": "15.222.226.83", - "port": 443 - }, - { - "ip": "15.222.226.83", - "port": 2087 - }, - { - "ip": "15.222.226.83", - "port": 3005 - }, - { - "ip": "15.222.226.83", - "port": 8080 - }, - { - "ip": "18.220.88.3", - "port": 80 - }, - { - "ip": "18.220.88.3", - "port": 443 - }, - { - "ip": "18.220.88.3", - "port": 3000 - }, - { - "ip": "35.240.149.15", - "port": 80 - }, - { - "ip": "35.240.149.15", - "port": 443 - }, - { - "ip": "35.240.149.15", - "port": 3000 - }, - { - "ip": "35.240.149.15", - "port": 8080 - }, - { - "ip": "81.68.121.84", - "port": 80 - }, - { - "ip": "81.68.121.84", - "port": 443 - }, - { - "ip": "81.68.121.84", - "port": 8080 - }, - { - "ip": "90.105.98.163", - "port": 80 - }, - { - "ip": "90.105.98.163", - "port": 443 - }, - { - "ip": "90.105.98.163", - "port": 8080 - }, - { - "ip": "178.62.12.238", - "port": 80 - }, - { - "ip": "178.62.12.238", - "port": 443 - }, - { - "ip": "178.62.12.238", - "port": 8010 - }, - { - "ip": "178.62.12.238", - "port": 8044 - }, - { - "ip": "178.62.12.238", - "port": 8080 - }, - { - "ip": "178.62.12.238", - "port": 8084 - }, - { - "ip": "178.62.12.238", - "port": 8087 - }, - { - "ip": "178.62.12.238", - "port": 8100 - }, - { - "ip": "5.45.108.238", - "port": 80 - }, - { - "ip": "5.45.108.238", - "port": 95 - }, - { - "ip": "5.45.108.238", - "port": 443 - }, - { - "ip": "5.45.108.238", - "port": 1334 - }, - { - "ip": "5.45.108.238", - "port": 1335 - }, - { - "ip": "5.45.108.238", - "port": 1337 - }, - { - "ip": "5.45.108.238", - "port": 1338 - }, - { - "ip": "5.45.108.238", - "port": 1339 - }, - { - "ip": "5.45.108.238", - "port": 4321 - }, - { - "ip": "5.45.108.238", - "port": 10080 - }, - { - "ip": "13.39.73.99", - "port": 80 - }, - { - "ip": "59.22.122.227", - "port": 80 - }, - { - "ip": "59.22.122.227", - "port": 84 - }, - { - "ip": "59.22.122.227", - "port": 8080 - }, - { - "ip": "59.22.122.227", - "port": 9935 - }, - { - "ip": "120.77.237.242", - "port": 80 - }, - { - "ip": "120.77.237.242", - "port": 801 - }, - { - "ip": "120.77.237.242", - "port": 8080 - }, - { - "ip": "120.77.237.242", - "port": 8081 - }, - { - "ip": "120.77.237.242", - "port": 8180 - }, - { - "ip": "120.77.237.242", - "port": 8182 - }, - { - "ip": "120.77.237.242", - "port": 9099 - }, - { - "ip": "120.77.237.242", - "port": 9999 - }, - { - "ip": "134.65.129.5", - "port": 80 - }, - { - "ip": "134.65.129.5", - "port": 8080 - }, - { - "ip": "134.65.129.5", - "port": 51007 - }, - { - "ip": "165.232.163.101", - "port": 80 - }, - { - "ip": "165.232.163.101", - "port": 443 - }, - { - "ip": "165.232.163.101", - "port": 8080 - }, - { - "ip": "185.130.105.15", - "port": 5000 - }, - { - "ip": "185.130.105.15", - "port": 7000 - }, - { - "ip": "185.130.105.15", - "port": 8080 - }, - { - "ip": "185.130.105.15", - "port": 8083 - }, - { - "ip": "185.130.105.15", - "port": 9100 - }, - { - "ip": "185.130.105.15", - "port": 25080 - }, - { - "ip": "185.223.95.136", - "port": 5000 - }, - { - "ip": "185.223.95.136", - "port": 7000 - }, - { - "ip": "185.223.95.136", - "port": 8080 - }, - { - "ip": "185.223.95.136", - "port": 8083 - }, - { - "ip": "185.223.95.136", - "port": 9100 - }, - { - "ip": "185.223.95.136", - "port": 25080 - }, - { - "ip": "1.14.99.75", - "port": 80 - }, - { - "ip": "1.14.99.75", - "port": 443 - }, - { - "ip": "1.14.99.75", - "port": 888 - }, - { - "ip": "1.14.99.75", - "port": 1200 - }, - { - "ip": "1.14.99.75", - "port": 8080 - }, - { - "ip": "1.14.99.75", - "port": 8888 - }, - { - "ip": "1.14.99.75", - "port": 8989 - }, - { - "ip": "3.111.158.187", - "port": 80 - }, - { - "ip": "3.111.158.187", - "port": 443 - }, - { - "ip": "3.111.158.187", - "port": 7002 - }, - { - "ip": "3.111.158.187", - "port": 8000 - }, - { - "ip": "3.111.158.187", - "port": 8001 - }, - { - "ip": "3.111.158.187", - "port": 8585 - }, - { - "ip": "3.111.158.187", - "port": 8686 - }, - { - "ip": "3.111.158.187", - "port": 8989 - }, - { - "ip": "35.177.80.154", - "port": 80 - }, - { - "ip": "35.177.80.154", - "port": 8080 - }, - { - "ip": "35.188.112.83", - "port": 80 - }, - { - "ip": "35.188.112.83", - "port": 8080 - }, - { - "ip": "35.188.112.83", - "port": 8081 - }, - { - "ip": "51.222.0.76", - "port": 80 - }, - { - "ip": "51.222.0.76", - "port": 443 - }, - { - "ip": "51.222.0.76", - "port": 7777 - }, - { - "ip": "51.222.0.76", - "port": 8080 - }, - { - "ip": "157.230.63.252", - "port": 80 - }, - { - "ip": "157.230.63.252", - "port": 443 - }, - { - "ip": "157.230.63.252", - "port": 5010 - }, - { - "ip": "157.230.63.252", - "port": 8080 - }, - { - "ip": "157.230.63.252", - "port": 8081 - }, - { - "ip": "185.143.45.51", - "port": 80 - }, - { - "ip": "185.143.45.51", - "port": 443 - }, - { - "ip": "185.143.45.51", - "port": 8066 - }, - { - "ip": "185.143.45.51", - "port": 8081 - }, - { - "ip": "188.165.221.101", - "port": 80 - }, - { - "ip": "188.165.221.101", - "port": 3002 - }, - { - "ip": "188.165.221.101", - "port": 3130 - }, - { - "ip": "188.165.221.101", - "port": 8080 - }, - { - "ip": "207.180.220.37", - "port": 80 - }, - { - "ip": "207.180.220.37", - "port": 443 - }, - { - "ip": "207.180.220.37", - "port": 3128 - }, - { - "ip": "207.180.220.37", - "port": 8000 - }, - { - "ip": "207.180.220.37", - "port": 8001 - }, - { - "ip": "207.180.220.37", - "port": 8008 - }, - { - "ip": "207.180.220.37", - "port": 8081 - }, - { - "ip": "207.180.220.37", - "port": 8800 - }, - { - "ip": "207.180.220.37", - "port": 8888 - }, - { - "ip": "207.180.220.37", - "port": 8889 - }, - { - "ip": "207.180.220.37", - "port": 8980 - }, - { - "ip": "207.180.220.37", - "port": 9090 - }, - { - "ip": "207.180.220.37", - "port": 50000 - }, - { - "ip": "217.160.103.58", - "port": 80 - }, - { - "ip": "217.160.103.58", - "port": 443 - }, - { - "ip": "217.160.103.58", - "port": 8080 - }, - { - "ip": "221.148.123.70", - "port": 80 - }, - { - "ip": "221.148.123.70", - "port": 84 - }, - { - "ip": "221.148.123.70", - "port": 443 - }, - { - "ip": "221.148.123.70", - "port": 8080 - }, - { - "ip": "221.148.123.70", - "port": 9935 - }, - { - "ip": "54.173.222.137", - "port": 80 - }, - { - "ip": "54.173.222.137", - "port": 443 - }, - { - "ip": "5.161.130.111", - "port": 80 - }, - { - "ip": "5.161.130.111", - "port": 5000 - }, - { - "ip": "45.76.250.195", - "port": 80 - }, - { - "ip": "45.76.250.195", - "port": 443 - }, - { - "ip": "45.76.250.195", - "port": 3010 - }, - { - "ip": "45.76.250.195", - "port": 3011 - }, - { - "ip": "45.76.250.195", - "port": 3025 - }, - { - "ip": "45.76.250.195", - "port": 3030 - }, - { - "ip": "45.76.250.195", - "port": 8090 - }, - { - "ip": "45.76.250.195", - "port": 8448 - }, - { - "ip": "47.87.148.135", - "port": 80 - }, - { - "ip": "47.87.148.135", - "port": 443 - }, - { - "ip": "47.87.148.135", - "port": 8080 - }, - { - "ip": "47.87.148.135", - "port": 12345 - }, - { - "ip": "49.12.3.61", - "port": 80 - }, - { - "ip": "49.12.3.61", - "port": 443 - }, - { - "ip": "49.12.3.61", - "port": 4000 - }, - { - "ip": "49.12.3.61", - "port": 7001 - }, - { - "ip": "49.12.3.61", - "port": 8080 - }, - { - "ip": "82.213.209.149", - "port": 3000 - }, - { - "ip": "82.213.209.149", - "port": 3333 - }, - { - "ip": "82.213.209.149", - "port": 7547 - }, - { - "ip": "82.213.209.149", - "port": 8081 - }, - { - "ip": "35.198.57.113", - "port": 80 - }, - { - "ip": "35.198.57.113", - "port": 8080 - }, - { - "ip": "35.198.57.113", - "port": 8081 - }, - { - "ip": "52.83.110.72", - "port": 80 - }, - { - "ip": "52.202.120.26", - "port": 80 - }, - { - "ip": "61.35.17.130", - "port": 443 - }, - { - "ip": "61.35.17.130", - "port": 8080 - }, - { - "ip": "89.58.18.12", - "port": 80 - }, - { - "ip": "89.58.18.12", - "port": 3000 - }, - { - "ip": "89.58.18.12", - "port": 3001 - }, - { - "ip": "89.58.18.12", - "port": 3002 - }, - { - "ip": "89.58.18.12", - "port": 18111 - }, - { - "ip": "107.189.7.66", - "port": 8000 - }, - { - "ip": "107.189.7.66", - "port": 9001 - }, - { - "ip": "107.189.7.66", - "port": 9003 - }, - { - "ip": "107.189.7.66", - "port": 9005 - }, - { - "ip": "107.189.7.66", - "port": 9007 - }, - { - "ip": "107.189.7.66", - "port": 9009 - }, - { - "ip": "107.189.7.66", - "port": 9011 - }, - { - "ip": "107.189.7.66", - "port": 9013 - }, - { - "ip": "107.189.7.66", - "port": 9015 - }, - { - "ip": "107.189.7.66", - "port": 9443 - }, - { - "ip": "191.101.235.244", - "port": 80 - }, - { - "ip": "191.101.235.244", - "port": 443 - }, - { - "ip": "191.101.235.244", - "port": 5245 - }, - { - "ip": "191.101.235.244", - "port": 7080 - }, - { - "ip": "191.101.235.244", - "port": 8000 - }, - { - "ip": "191.101.235.244", - "port": 8001 - }, - { - "ip": "191.101.235.244", - "port": 8082 - }, - { - "ip": "191.101.235.244", - "port": 8090 - }, - { - "ip": "191.101.235.244", - "port": 9001 - }, - { - "ip": "191.101.235.244", - "port": 9443 - }, - { - "ip": "54.37.18.100", - "port": 80 - }, - { - "ip": "54.37.18.100", - "port": 443 - }, - { - "ip": "54.37.18.100", - "port": 8090 - }, - { - "ip": "3.76.10.27", - "port": 3001 - }, - { - "ip": "3.76.10.27", - "port": 3002 - }, - { - "ip": "35.241.97.229", - "port": 80 - }, - { - "ip": "35.241.97.229", - "port": 5000 - }, - { - "ip": "35.241.97.229", - "port": 8080 - }, - { - "ip": "81.71.143.13", - "port": 80 - }, - { - "ip": "81.71.143.13", - "port": 443 - }, - { - "ip": "81.71.143.13", - "port": 888 - }, - { - "ip": "81.71.143.13", - "port": 1200 - }, - { - "ip": "81.71.143.13", - "port": 3000 - }, - { - "ip": "81.71.143.13", - "port": 4000 - }, - { - "ip": "81.71.143.13", - "port": 4001 - }, - { - "ip": "81.71.143.13", - "port": 5244 - }, - { - "ip": "81.71.143.13", - "port": 5566 - }, - { - "ip": "81.71.143.13", - "port": 7000 - }, - { - "ip": "81.71.143.13", - "port": 8080 - }, - { - "ip": "81.71.143.13", - "port": 8081 - }, - { - "ip": "81.71.143.13", - "port": 8082 - }, - { - "ip": "81.71.143.13", - "port": 8083 - }, - { - "ip": "81.71.143.13", - "port": 8123 - }, - { - "ip": "81.71.143.13", - "port": 8181 - }, - { - "ip": "112.216.185.178", - "port": 81 - }, - { - "ip": "112.216.185.178", - "port": 443 - }, - { - "ip": "112.216.185.178", - "port": 8080 - }, - { - "ip": "187.92.103.154", - "port": 80 - }, - { - "ip": "187.92.103.154", - "port": 7070 - }, - { - "ip": "187.92.103.154", - "port": 8601 - }, - { - "ip": "187.92.103.154", - "port": 8800 - }, - { - "ip": "187.92.103.154", - "port": 9090 - }, - { - "ip": "187.92.103.154", - "port": 9091 - }, - { - "ip": "187.92.103.154", - "port": 9100 - }, - { - "ip": "187.92.103.154", - "port": 9595 - }, - { - "ip": "187.92.103.154", - "port": 9994 - }, - { - "ip": "187.92.103.154", - "port": 9999 - }, - { - "ip": "210.91.88.194", - "port": 80 - }, - { - "ip": "210.91.88.194", - "port": 84 - }, - { - "ip": "210.91.88.194", - "port": 8080 - }, - { - "ip": "210.91.88.194", - "port": 9935 - }, - { - "ip": "216.48.176.118", - "port": 80 - }, - { - "ip": "216.48.176.118", - "port": 82 - }, - { - "ip": "216.48.176.118", - "port": 443 - }, - { - "ip": "216.48.176.118", - "port": 3000 - }, - { - "ip": "216.48.176.118", - "port": 5001 - }, - { - "ip": "216.48.176.118", - "port": 6969 - }, - { - "ip": "216.48.176.118", - "port": 8000 - }, - { - "ip": "216.48.176.118", - "port": 8181 - }, - { - "ip": "65.52.0.242", - "port": 80 - }, - { - "ip": "65.52.0.242", - "port": 443 - }, - { - "ip": "65.52.0.242", - "port": 8080 - }, - { - "ip": "65.52.0.242", - "port": 8081 - }, - { - "ip": "37.18.110.222", - "port": 80 - }, - { - "ip": "37.18.110.222", - "port": 443 - }, - { - "ip": "37.18.110.222", - "port": 3000 - }, - { - "ip": "37.18.110.222", - "port": 4000 - }, - { - "ip": "37.18.110.222", - "port": 4443 - }, - { - "ip": "37.18.110.222", - "port": 5000 - }, - { - "ip": "37.18.110.222", - "port": 7000 - }, - { - "ip": "37.18.110.222", - "port": 8080 - }, - { - "ip": "37.18.110.222", - "port": 8081 - }, - { - "ip": "37.18.110.222", - "port": 8989 - }, - { - "ip": "37.18.110.222", - "port": 9090 - }, - { - "ip": "52.24.182.224", - "port": 443 - }, - { - "ip": "52.24.182.224", - "port": 8080 - }, - { - "ip": "138.68.71.208", - "port": 80 - }, - { - "ip": "138.68.71.208", - "port": 443 - }, - { - "ip": "35.92.46.155", - "port": 8080 - }, - { - "ip": "39.98.177.94", - "port": 80 - }, - { - "ip": "39.98.177.94", - "port": 443 - }, - { - "ip": "39.98.177.94", - "port": 3001 - }, - { - "ip": "39.98.177.94", - "port": 4001 - }, - { - "ip": "44.204.214.232", - "port": 3000 - }, - { - "ip": "44.204.214.232", - "port": 8080 - }, - { - "ip": "52.203.161.118", - "port": 80 - }, - { - "ip": "52.203.161.118", - "port": 443 - }, - { - "ip": "52.203.161.118", - "port": 8080 - }, - { - "ip": "52.203.161.118", - "port": 8081 - }, - { - "ip": "52.203.161.118", - "port": 8282 - }, - { - "ip": "52.203.161.118", - "port": 9000 - }, - { - "ip": "54.166.171.122", - "port": 80 - }, - { - "ip": "54.166.171.122", - "port": 443 - }, - { - "ip": "54.166.171.122", - "port": 8080 - }, - { - "ip": "144.202.45.173", - "port": 80 - }, - { - "ip": "144.202.45.173", - "port": 443 - }, - { - "ip": "144.202.45.173", - "port": 8080 - }, - { - "ip": "157.245.48.239", - "port": 80 - }, - { - "ip": "157.245.48.239", - "port": 8080 - }, - { - "ip": "173.255.231.227", - "port": 80 - }, - { - "ip": "173.255.231.227", - "port": 443 - }, - { - "ip": "173.255.231.227", - "port": 1337 - }, - { - "ip": "173.255.231.227", - "port": 8001 - }, - { - "ip": "173.255.231.227", - "port": 8004 - }, - { - "ip": "173.255.231.227", - "port": 9000 - }, - { - "ip": "173.255.231.227", - "port": 9001 - }, - { - "ip": "173.255.231.227", - "port": 9012 - }, - { - "ip": "173.255.231.227", - "port": 9013 - }, - { - "ip": "173.255.231.227", - "port": 9015 - }, - { - "ip": "173.255.231.227", - "port": 9016 - }, - { - "ip": "173.255.231.227", - "port": 9017 - }, - { - "ip": "173.255.231.227", - "port": 9019 - }, - { - "ip": "173.255.231.227", - "port": 9020 - }, - { - "ip": "173.255.231.227", - "port": 9021 - }, - { - "ip": "173.255.231.227", - "port": 9023 - }, - { - "ip": "173.255.231.227", - "port": 9024 - }, - { - "ip": "173.255.231.227", - "port": 9025 - }, - { - "ip": "173.255.231.227", - "port": 9026 - }, - { - "ip": "173.255.231.227", - "port": 9027 - }, - { - "ip": "173.255.231.227", - "port": 9028 - }, - { - "ip": "173.255.231.227", - "port": 9030 - }, - { - "ip": "173.255.231.227", - "port": 9031 - }, - { - "ip": "173.255.231.227", - "port": 9033 - }, - { - "ip": "173.255.231.227", - "port": 9038 - }, - { - "ip": "173.255.231.227", - "port": 9039 - }, - { - "ip": "173.255.231.227", - "port": 9044 - }, - { - "ip": "173.255.231.227", - "port": 9350 - }, - { - "ip": "173.255.231.227", - "port": 9400 - }, - { - "ip": "173.255.231.227", - "port": 9401 - }, - { - "ip": "173.255.231.227", - "port": 9500 - }, - { - "ip": "173.255.231.227", - "port": 9501 - }, - { - "ip": "173.255.231.227", - "port": 9600 - }, - { - "ip": "211.118.245.242", - "port": 80 - }, - { - "ip": "211.118.245.242", - "port": 443 - }, - { - "ip": "211.118.245.242", - "port": 30080 - }, - { - "ip": "35.80.169.94", - "port": 80 - }, - { - "ip": "35.80.169.94", - "port": 443 - }, - { - "ip": "18.228.118.52", - "port": 4000 - }, - { - "ip": "18.228.118.52", - "port": 6000 - }, - { - "ip": "18.228.118.52", - "port": 6050 - }, - { - "ip": "18.228.118.52", - "port": 7000 - }, - { - "ip": "18.228.118.52", - "port": 7050 - }, - { - "ip": "18.228.118.52", - "port": 7500 - }, - { - "ip": "18.228.118.52", - "port": 7777 - }, - { - "ip": "18.228.118.52", - "port": 8000 - }, - { - "ip": "18.228.118.52", - "port": 8001 - }, - { - "ip": "18.228.118.52", - "port": 8050 - }, - { - "ip": "18.228.118.52", - "port": 8700 - }, - { - "ip": "18.228.118.52", - "port": 9001 - }, - { - "ip": "18.228.118.52", - "port": 9005 - }, - { - "ip": "18.228.118.52", - "port": 9006 - }, - { - "ip": "18.228.118.52", - "port": 9008 - }, - { - "ip": "18.228.118.52", - "port": 9010 - }, - { - "ip": "18.228.118.52", - "port": 9011 - }, - { - "ip": "18.228.118.52", - "port": 9999 - }, - { - "ip": "18.228.118.52", - "port": 30000 - }, - { - "ip": "18.232.126.50", - "port": 80 - }, - { - "ip": "27.35.131.31", - "port": 80 - }, - { - "ip": "27.35.131.31", - "port": 84 - }, - { - "ip": "27.35.131.31", - "port": 6500 - }, - { - "ip": "27.35.131.31", - "port": 8080 - }, - { - "ip": "27.35.131.31", - "port": 8090 - }, - { - "ip": "35.197.110.103", - "port": 5440 - }, - { - "ip": "35.197.110.103", - "port": 5487 - }, - { - "ip": "35.197.110.103", - "port": 5556 - }, - { - "ip": "35.197.110.103", - "port": 5567 - }, - { - "ip": "35.197.110.103", - "port": 5707 - }, - { - "ip": "35.197.110.103", - "port": 5708 - }, - { - "ip": "35.197.110.103", - "port": 5728 - }, - { - "ip": "35.197.110.103", - "port": 5760 - }, - { - "ip": "35.197.110.103", - "port": 5903 - }, - { - "ip": "35.197.110.103", - "port": 5907 - }, - { - "ip": "35.197.110.103", - "port": 5918 - }, - { - "ip": "35.197.110.103", - "port": 5919 - }, - { - "ip": "35.197.110.103", - "port": 5920 - }, - { - "ip": "35.197.110.103", - "port": 5985 - }, - { - "ip": "35.197.110.103", - "port": 6055 - }, - { - "ip": "35.197.110.103", - "port": 6123 - }, - { - "ip": "35.197.110.103", - "port": 6264 - }, - { - "ip": "35.197.110.103", - "port": 6448 - }, - { - "ip": "35.197.110.103", - "port": 6548 - }, - { - "ip": "35.197.110.103", - "port": 6700 - }, - { - "ip": "35.197.110.103", - "port": 6807 - }, - { - "ip": "35.197.110.103", - "port": 7007 - }, - { - "ip": "35.197.110.103", - "port": 7012 - }, - { - "ip": "35.197.110.103", - "port": 7018 - }, - { - "ip": "35.197.110.103", - "port": 7090 - }, - { - "ip": "35.197.110.103", - "port": 7112 - }, - { - "ip": "35.197.110.103", - "port": 7262 - }, - { - "ip": "35.197.110.103", - "port": 7375 - }, - { - "ip": "35.197.110.103", - "port": 7480 - }, - { - "ip": "35.197.110.103", - "port": 7636 - }, - { - "ip": "35.197.110.103", - "port": 7801 - }, - { - "ip": "35.197.110.103", - "port": 7979 - }, - { - "ip": "35.197.110.103", - "port": 7982 - }, - { - "ip": "35.197.110.103", - "port": 8009 - }, - { - "ip": "35.197.110.103", - "port": 8012 - }, - { - "ip": "35.197.110.103", - "port": 8017 - }, - { - "ip": "35.197.110.103", - "port": 8018 - }, - { - "ip": "35.197.110.103", - "port": 8033 - }, - { - "ip": "35.197.110.103", - "port": 8053 - }, - { - "ip": "35.197.110.103", - "port": 8054 - }, - { - "ip": "35.197.110.103", - "port": 8066 - }, - { - "ip": "35.197.110.103", - "port": 8075 - }, - { - "ip": "51.250.31.204", - "port": 80 - }, - { - "ip": "51.250.31.204", - "port": 443 - }, - { - "ip": "51.250.31.204", - "port": 7000 - }, - { - "ip": "51.250.31.204", - "port": 7300 - }, - { - "ip": "51.250.31.204", - "port": 7350 - }, - { - "ip": "51.250.31.204", - "port": 7500 - }, - { - "ip": "51.250.31.204", - "port": 7550 - }, - { - "ip": "51.250.31.204", - "port": 7600 - }, - { - "ip": "51.250.31.204", - "port": 7750 - }, - { - "ip": "51.250.31.204", - "port": 8887 - }, - { - "ip": "51.250.31.204", - "port": 8888 - }, - { - "ip": "144.217.252.163", - "port": 80 - }, - { - "ip": "144.217.252.163", - "port": 443 - }, - { - "ip": "144.217.252.163", - "port": 1337 - }, - { - "ip": "144.217.252.163", - "port": 4444 - }, - { - "ip": "144.217.252.163", - "port": 5000 - }, - { - "ip": "144.217.252.163", - "port": 8077 - }, - { - "ip": "144.217.252.163", - "port": 8078 - }, - { - "ip": "144.217.252.163", - "port": 8080 - }, - { - "ip": "144.217.252.163", - "port": 8081 - }, - { - "ip": "144.217.252.163", - "port": 8195 - }, - { - "ip": "144.217.252.163", - "port": 8443 - }, - { - "ip": "144.217.252.163", - "port": 8686 - }, - { - "ip": "144.217.252.163", - "port": 8787 - }, - { - "ip": "144.217.252.163", - "port": 8999 - }, - { - "ip": "144.217.252.163", - "port": 9990 - }, - { - "ip": "188.166.216.187", - "port": 80 - }, - { - "ip": "188.166.216.187", - "port": 443 - }, - { - "ip": "188.166.216.187", - "port": 5000 - }, - { - "ip": "188.166.216.187", - "port": 8080 - }, - { - "ip": "92.204.137.120", - "port": 80 - }, - { - "ip": "92.204.137.120", - "port": 443 - }, - { - "ip": "92.204.137.120", - "port": 2077 - }, - { - "ip": "92.204.137.120", - "port": 2078 - }, - { - "ip": "92.204.137.120", - "port": 2082 - }, - { - "ip": "92.204.137.120", - "port": 2083 - }, - { - "ip": "92.204.137.120", - "port": 2086 - }, - { - "ip": "92.204.137.120", - "port": 2087 - }, - { - "ip": "92.204.137.120", - "port": 2091 - }, - { - "ip": "92.204.137.120", - "port": 2095 - }, - { - "ip": "92.204.137.120", - "port": 2096 - }, - { - "ip": "92.204.137.120", - "port": 3000 - }, - { - "ip": "92.204.137.120", - "port": 3200 - }, - { - "ip": "92.204.137.120", - "port": 7000 - }, - { - "ip": "92.204.137.120", - "port": 7200 - }, - { - "ip": "34.201.198.214", - "port": 80 - }, - { - "ip": "34.201.198.214", - "port": 443 - }, - { - "ip": "34.201.198.214", - "port": 8010 - }, - { - "ip": "37.58.63.233", - "port": 80 - }, - { - "ip": "37.58.63.233", - "port": 443 - }, - { - "ip": "37.58.63.233", - "port": 3000 - }, - { - "ip": "37.58.63.233", - "port": 8080 - }, - { - "ip": "124.107.90.133", - "port": 80 - }, - { - "ip": "124.107.90.133", - "port": 443 - }, - { - "ip": "124.107.90.133", - "port": 8888 - }, - { - "ip": "142.132.181.0", - "port": 80 - }, - { - "ip": "142.132.181.0", - "port": 443 - }, - { - "ip": "142.132.181.0", - "port": 8089 - }, - { - "ip": "161.111.47.31", - "port": 80 - }, - { - "ip": "161.111.47.31", - "port": 443 - }, - { - "ip": "161.111.47.31", - "port": 8008 - }, - { - "ip": "161.111.47.31", - "port": 8015 - }, - { - "ip": "161.111.47.31", - "port": 8080 - }, - { - "ip": "174.138.58.253", - "port": 3000 - }, - { - "ip": "174.138.58.253", - "port": 8000 - }, - { - "ip": "177.38.191.251", - "port": 80 - }, - { - "ip": "177.38.191.251", - "port": 443 - }, - { - "ip": "177.38.191.251", - "port": 6160 - }, - { - "ip": "177.38.191.251", - "port": 8091 - }, - { - "ip": "177.38.191.251", - "port": 8098 - }, - { - "ip": "185.209.163.6", - "port": 5000 - }, - { - "ip": "185.209.163.6", - "port": 7000 - }, - { - "ip": "185.209.163.6", - "port": 7200 - }, - { - "ip": "185.209.163.6", - "port": 8080 - }, - { - "ip": "185.209.163.6", - "port": 8083 - }, - { - "ip": "185.209.163.6", - "port": 9100 - }, - { - "ip": "172.104.173.245", - "port": 80 - }, - { - "ip": "172.104.173.245", - "port": 443 - }, - { - "ip": "172.104.173.245", - "port": 3334 - }, - { - "ip": "172.104.173.245", - "port": 5000 - }, - { - "ip": "172.104.173.245", - "port": 8080 - }, - { - "ip": "172.104.173.245", - "port": 13003 - }, - { - "ip": "172.104.173.245", - "port": 13028 - }, - { - "ip": "172.104.173.245", - "port": 13038 - }, - { - "ip": "172.104.173.245", - "port": 13091 - }, - { - "ip": "172.104.173.245", - "port": 14015 - }, - { - "ip": "197.189.230.202", - "port": 443 - }, - { - "ip": "197.189.230.202", - "port": 5985 - }, - { - "ip": "197.189.230.202", - "port": 8083 - }, - { - "ip": "197.189.230.202", - "port": 8084 - }, - { - "ip": "197.189.230.202", - "port": 9953 - }, - { - "ip": "197.189.230.202", - "port": 65534 - }, - { - "ip": "35.82.102.185", - "port": 80 - }, - { - "ip": "58.151.137.106", - "port": 80 - }, - { - "ip": "58.151.137.106", - "port": 8080 - }, - { - "ip": "65.1.8.175", - "port": 80 - }, - { - "ip": "220.85.51.10", - "port": 80 - }, - { - "ip": "220.85.51.10", - "port": 84 - }, - { - "ip": "220.85.51.10", - "port": 8080 - }, - { - "ip": "220.85.51.10", - "port": 9935 - }, - { - "ip": "222.99.197.229", - "port": 84 - }, - { - "ip": "222.99.197.229", - "port": 443 - }, - { - "ip": "222.99.197.229", - "port": 8080 - }, - { - "ip": "222.99.197.229", - "port": 9935 - }, - { - "ip": "52.18.165.206", - "port": 80 - }, - { - "ip": "52.18.165.206", - "port": 443 - }, - { - "ip": "34.83.185.186", - "port": 80 - }, - { - "ip": "34.83.185.186", - "port": 443 - }, - { - "ip": "34.83.185.186", - "port": 3000 - }, - { - "ip": "34.95.166.78", - "port": 80 - }, - { - "ip": "34.95.166.78", - "port": 8080 - }, - { - "ip": "34.95.166.78", - "port": 8081 - }, - { - "ip": "35.224.115.157", - "port": 30050 - }, - { - "ip": "35.224.115.157", - "port": 30111 - }, - { - "ip": "35.224.115.157", - "port": 30120 - }, - { - "ip": "35.224.115.157", - "port": 30169 - }, - { - "ip": "35.224.115.157", - "port": 30386 - }, - { - "ip": "35.224.115.157", - "port": 30473 - }, - { - "ip": "35.224.115.157", - "port": 30506 - }, - { - "ip": "35.224.115.157", - "port": 30666 - }, - { - "ip": "35.224.115.157", - "port": 30700 - }, - { - "ip": "35.224.115.157", - "port": 30710 - }, - { - "ip": "35.224.115.157", - "port": 30729 - }, - { - "ip": "35.224.115.157", - "port": 30961 - }, - { - "ip": "35.224.115.157", - "port": 30973 - }, - { - "ip": "35.224.115.157", - "port": 31017 - }, - { - "ip": "35.224.115.157", - "port": 31049 - }, - { - "ip": "35.224.115.157", - "port": 31086 - }, - { - "ip": "35.224.115.157", - "port": 31353 - }, - { - "ip": "35.224.115.157", - "port": 31420 - }, - { - "ip": "35.224.115.157", - "port": 31681 - }, - { - "ip": "35.224.115.157", - "port": 31725 - }, - { - "ip": "35.224.115.157", - "port": 31742 - }, - { - "ip": "35.224.115.157", - "port": 31784 - }, - { - "ip": "35.224.115.157", - "port": 31870 - }, - { - "ip": "35.224.115.157", - "port": 31872 - }, - { - "ip": "35.224.115.157", - "port": 31901 - }, - { - "ip": "35.224.115.157", - "port": 31973 - }, - { - "ip": "35.224.115.157", - "port": 32092 - }, - { - "ip": "35.224.115.157", - "port": 32124 - }, - { - "ip": "35.224.115.157", - "port": 32173 - }, - { - "ip": "35.224.115.157", - "port": 32248 - }, - { - "ip": "35.224.115.157", - "port": 32262 - }, - { - "ip": "35.224.115.157", - "port": 32280 - }, - { - "ip": "35.224.115.157", - "port": 32289 - }, - { - "ip": "35.224.115.157", - "port": 32526 - }, - { - "ip": "35.224.115.157", - "port": 32709 - }, - { - "ip": "35.224.115.157", - "port": 32731 - }, - { - "ip": "44.224.43.249", - "port": 80 - }, - { - "ip": "49.0.72.59", - "port": 80 - }, - { - "ip": "49.0.72.59", - "port": 81 - }, - { - "ip": "49.0.72.59", - "port": 443 - }, - { - "ip": "49.0.72.59", - "port": 1337 - }, - { - "ip": "49.0.72.59", - "port": 3001 - }, - { - "ip": "49.0.72.59", - "port": 3005 - }, - { - "ip": "49.0.72.59", - "port": 3101 - }, - { - "ip": "49.0.72.59", - "port": 3105 - }, - { - "ip": "49.0.72.59", - "port": 4000 - }, - { - "ip": "49.0.72.59", - "port": 5985 - }, - { - "ip": "49.0.72.59", - "port": 7002 - }, - { - "ip": "49.0.72.59", - "port": 8001 - }, - { - "ip": "49.0.72.59", - "port": 8081 - }, - { - "ip": "49.0.72.59", - "port": 8084 - }, - { - "ip": "49.0.72.59", - "port": 9000 - }, - { - "ip": "49.0.72.59", - "port": 47001 - }, - { - "ip": "52.87.50.238", - "port": 80 - }, - { - "ip": "52.87.50.238", - "port": 443 - }, - { - "ip": "71.201.168.173", - "port": 80 - }, - { - "ip": "71.201.168.173", - "port": 443 - }, - { - "ip": "71.201.168.173", - "port": 32400 - }, - { - "ip": "134.209.108.195", - "port": 80 - }, - { - "ip": "134.209.108.195", - "port": 443 - }, - { - "ip": "134.209.108.195", - "port": 3000 - }, - { - "ip": "134.209.108.195", - "port": 5050 - }, - { - "ip": "134.209.108.195", - "port": 7099 - }, - { - "ip": "134.209.108.195", - "port": 8080 - }, - { - "ip": "134.209.108.195", - "port": 8086 - }, - { - "ip": "134.209.108.195", - "port": 8443 - }, - { - "ip": "134.209.108.195", - "port": 8834 - }, - { - "ip": "138.201.193.144", - "port": 3000 - }, - { - "ip": "138.201.193.144", - "port": 9001 - }, - { - "ip": "138.201.193.144", - "port": 9002 - }, - { - "ip": "138.201.193.144", - "port": 9005 - }, - { - "ip": "138.201.193.144", - "port": 9010 - }, - { - "ip": "138.201.193.144", - "port": 9045 - }, - { - "ip": "138.201.193.144", - "port": 9050 - }, - { - "ip": "138.201.193.144", - "port": 9060 - }, - { - "ip": "138.201.193.144", - "port": 9065 - }, - { - "ip": "138.201.193.144", - "port": 9070 - }, - { - "ip": "138.201.193.144", - "port": 9075 - }, - { - "ip": "138.201.193.144", - "port": 9080 - }, - { - "ip": "138.201.193.144", - "port": 9085 - }, - { - "ip": "138.201.193.144", - "port": 9090 - }, - { - "ip": "138.201.193.144", - "port": 9095 - }, - { - "ip": "138.201.193.144", - "port": 9100 - }, - { - "ip": "138.201.193.144", - "port": 9105 - }, - { - "ip": "138.201.193.144", - "port": 9115 - }, - { - "ip": "138.201.193.144", - "port": 9121 - }, - { - "ip": "138.201.193.144", - "port": 9130 - }, - { - "ip": "138.201.193.144", - "port": 9135 - }, - { - "ip": "138.201.193.144", - "port": 9140 - }, - { - "ip": "138.201.193.144", - "port": 9145 - }, - { - "ip": "138.201.193.144", - "port": 9150 - }, - { - "ip": "138.201.193.144", - "port": 9190 - }, - { - "ip": "138.201.193.144", - "port": 9195 - }, - { - "ip": "138.201.193.144", - "port": 9210 - }, - { - "ip": "138.201.193.144", - "port": 9215 - }, - { - "ip": "138.201.193.144", - "port": 9225 - }, - { - "ip": "138.201.193.144", - "port": 9230 - }, - { - "ip": "138.201.193.144", - "port": 9250 - }, - { - "ip": "138.201.193.144", - "port": 9255 - }, - { - "ip": "138.201.193.144", - "port": 9260 - }, - { - "ip": "138.201.193.144", - "port": 9270 - }, - { - "ip": "138.201.193.144", - "port": 9280 - }, - { - "ip": "138.201.193.144", - "port": 9300 - }, - { - "ip": "138.201.193.144", - "port": 9320 - }, - { - "ip": "138.201.193.144", - "port": 9340 - }, - { - "ip": "138.201.193.144", - "port": 9360 - }, - { - "ip": "138.201.193.144", - "port": 9370 - }, - { - "ip": "138.201.193.144", - "port": 9380 - }, - { - "ip": "138.201.193.144", - "port": 9390 - }, - { - "ip": "138.201.193.144", - "port": 9410 - }, - { - "ip": "138.201.193.144", - "port": 9470 - }, - { - "ip": "138.201.193.144", - "port": 9480 - }, - { - "ip": "138.201.193.144", - "port": 9510 - }, - { - "ip": "18.215.39.15", - "port": 80 - }, - { - "ip": "18.215.39.15", - "port": 443 - }, - { - "ip": "5.161.48.199", - "port": 80 - }, - { - "ip": "5.161.48.199", - "port": 5000 - }, - { - "ip": "51.195.216.77", - "port": 80 - }, - { - "ip": "51.195.216.77", - "port": 443 - }, - { - "ip": "51.195.216.77", - "port": 4000 - }, - { - "ip": "116.203.20.37", - "port": 80 - }, - { - "ip": "116.203.20.37", - "port": 443 - }, - { - "ip": "116.203.20.37", - "port": 8080 - }, - { - "ip": "165.227.142.116", - "port": 80 - }, - { - "ip": "188.134.73.136", - "port": 443 - }, - { - "ip": "188.134.73.136", - "port": 3000 - }, - { - "ip": "188.134.73.136", - "port": 9443 - }, - { - "ip": "188.134.73.136", - "port": 10001 - }, - { - "ip": "188.134.73.136", - "port": 10101 - }, - { - "ip": "188.134.73.136", - "port": 11300 - }, - { - "ip": "211.180.227.146", - "port": 80 - }, - { - "ip": "211.180.227.146", - "port": 84 - }, - { - "ip": "211.180.227.146", - "port": 443 - }, - { - "ip": "211.180.227.146", - "port": 8080 - }, - { - "ip": "109.106.1.163", - "port": 80 - }, - { - "ip": "109.106.1.163", - "port": 443 - }, - { - "ip": "109.106.1.163", - "port": 3000 - }, - { - "ip": "109.106.1.163", - "port": 3070 - }, - { - "ip": "109.106.1.163", - "port": 8081 - }, - { - "ip": "109.106.1.163", - "port": 8575 - }, - { - "ip": "109.106.1.163", - "port": 9069 - }, - { - "ip": "137.74.92.81", - "port": 80 - }, - { - "ip": "137.74.92.81", - "port": 3000 - }, - { - "ip": "137.74.92.81", - "port": 3002 - }, - { - "ip": "137.74.92.81", - "port": 3099 - }, - { - "ip": "137.74.92.81", - "port": 5000 - }, - { - "ip": "137.74.92.81", - "port": 6433 - }, - { - "ip": "137.74.92.81", - "port": 8081 - }, - { - "ip": "164.92.176.190", - "port": 8080 - }, - { - "ip": "221.150.69.132", - "port": 81 - }, - { - "ip": "221.150.69.132", - "port": 84 - }, - { - "ip": "221.150.69.132", - "port": 443 - }, - { - "ip": "221.150.69.132", - "port": 8080 - }, - { - "ip": "221.150.69.132", - "port": 9935 - }, - { - "ip": "3.237.104.64", - "port": 80 - }, - { - "ip": "3.237.104.64", - "port": 443 - }, - { - "ip": "34.73.26.174", - "port": 80 - }, - { - "ip": "34.73.26.174", - "port": 8080 - }, - { - "ip": "34.73.26.174", - "port": 8081 - }, - { - "ip": "34.228.215.31", - "port": 8080 - }, - { - "ip": "51.91.218.116", - "port": 80 - }, - { - "ip": "51.91.218.116", - "port": 443 - }, - { - "ip": "51.91.218.116", - "port": 30001 - }, - { - "ip": "51.91.218.116", - "port": 30003 - }, - { - "ip": "51.91.218.116", - "port": 30004 - }, - { - "ip": "51.91.218.116", - "port": 30005 - }, - { - "ip": "51.91.218.116", - "port": 30006 - }, - { - "ip": "51.91.218.116", - "port": 30007 - }, - { - "ip": "51.91.218.116", - "port": 30009 - }, - { - "ip": "51.91.218.116", - "port": 30010 - }, - { - "ip": "51.91.218.116", - "port": 30011 - }, - { - "ip": "51.91.218.116", - "port": 30012 - }, - { - "ip": "51.91.218.116", - "port": 30013 - }, - { - "ip": "51.91.218.116", - "port": 30015 - }, - { - "ip": "51.91.218.116", - "port": 30021 - }, - { - "ip": "51.91.218.116", - "port": 30023 - }, - { - "ip": "51.91.218.116", - "port": 30026 - }, - { - "ip": "51.91.218.116", - "port": 30027 - }, - { - "ip": "51.91.218.116", - "port": 30029 - }, - { - "ip": "51.91.218.116", - "port": 30032 - }, - { - "ip": "51.91.218.116", - "port": 30033 - }, - { - "ip": "51.91.218.116", - "port": 30035 - }, - { - "ip": "51.91.218.116", - "port": 30041 - }, - { - "ip": "51.91.218.116", - "port": 30047 - }, - { - "ip": "51.91.218.116", - "port": 30049 - }, - { - "ip": "51.91.218.116", - "port": 30065 - }, - { - "ip": "128.199.191.72", - "port": 80 - }, - { - "ip": "128.199.191.72", - "port": 251 - }, - { - "ip": "128.199.191.72", - "port": 995 - }, - { - "ip": "128.199.191.72", - "port": 999 - }, - { - "ip": "128.199.191.72", - "port": 1234 - }, - { - "ip": "128.199.191.72", - "port": 1235 - }, - { - "ip": "128.199.191.72", - "port": 1945 - }, - { - "ip": "128.199.191.72", - "port": 3000 - }, - { - "ip": "128.199.191.72", - "port": 3421 - }, - { - "ip": "128.199.191.72", - "port": 8080 - }, - { - "ip": "128.199.191.72", - "port": 8090 - }, - { - "ip": "128.199.191.72", - "port": 8181 - }, - { - "ip": "128.199.191.72", - "port": 9001 - }, - { - "ip": "128.199.191.72", - "port": 9002 - }, - { - "ip": "128.199.191.72", - "port": 9003 - }, - { - "ip": "128.199.191.72", - "port": 9004 - }, - { - "ip": "200.49.47.234", - "port": 222 - }, - { - "ip": "200.49.47.234", - "port": 1444 - }, - { - "ip": "200.49.47.234", - "port": 1651 - }, - { - "ip": "200.49.47.234", - "port": 2083 - }, - { - "ip": "200.49.47.234", - "port": 3146 - }, - { - "ip": "200.49.47.234", - "port": 8091 - }, - { - "ip": "200.49.47.234", - "port": 8092 - }, - { - "ip": "200.49.47.234", - "port": 8094 - }, - { - "ip": "200.49.47.234", - "port": 8121 - }, - { - "ip": "200.49.47.234", - "port": 8122 - }, - { - "ip": "200.49.47.234", - "port": 8133 - }, - { - "ip": "200.49.47.234", - "port": 8170 - }, - { - "ip": "200.49.47.234", - "port": 8171 - }, - { - "ip": "200.49.47.234", - "port": 8173 - }, - { - "ip": "200.49.47.234", - "port": 8174 - }, - { - "ip": "200.49.47.234", - "port": 8175 - }, - { - "ip": "200.49.47.234", - "port": 8176 - }, - { - "ip": "200.49.47.234", - "port": 8180 - }, - { - "ip": "200.49.47.234", - "port": 8181 - }, - { - "ip": "200.49.47.234", - "port": 8182 - }, - { - "ip": "200.49.47.234", - "port": 8183 - }, - { - "ip": "200.49.47.234", - "port": 8184 - }, - { - "ip": "200.49.47.234", - "port": 8185 - }, - { - "ip": "200.49.47.234", - "port": 8190 - }, - { - "ip": "200.49.47.234", - "port": 8192 - }, - { - "ip": "200.49.47.234", - "port": 8193 - }, - { - "ip": "200.49.47.234", - "port": 8194 - }, - { - "ip": "200.49.47.234", - "port": 8195 - }, - { - "ip": "200.49.47.234", - "port": 8196 - }, - { - "ip": "200.49.47.234", - "port": 8203 - }, - { - "ip": "200.49.47.234", - "port": 9999 - }, - { - "ip": "200.49.47.234", - "port": 10000 - }, - { - "ip": "200.49.47.234", - "port": 10011 - }, - { - "ip": "200.49.47.234", - "port": 10012 - }, - { - "ip": "200.49.47.234", - "port": 10013 - }, - { - "ip": "200.49.47.234", - "port": 10014 - }, - { - "ip": "200.49.47.234", - "port": 10015 - }, - { - "ip": "200.49.47.234", - "port": 10016 - }, - { - "ip": "200.49.47.234", - "port": 10017 - }, - { - "ip": "200.49.47.234", - "port": 10018 - }, - { - "ip": "200.49.47.234", - "port": 10101 - }, - { - "ip": "200.49.47.234", - "port": 10108 - }, - { - "ip": "200.49.47.234", - "port": 10123 - }, - { - "ip": "200.49.47.234", - "port": 14423 - }, - { - "ip": "200.49.47.234", - "port": 14424 - }, - { - "ip": "200.49.47.234", - "port": 18281 - }, - { - "ip": "200.49.47.234", - "port": 40016 - }, - { - "ip": "200.49.47.234", - "port": 61234 - }, - { - "ip": "211.107.220.190", - "port": 84 - }, - { - "ip": "211.107.220.190", - "port": 443 - }, - { - "ip": "211.107.220.190", - "port": 8080 - }, - { - "ip": "211.107.220.190", - "port": 9935 - }, - { - "ip": "211.171.32.146", - "port": 80 - }, - { - "ip": "211.171.32.146", - "port": 88 - }, - { - "ip": "211.171.32.146", - "port": 8080 - }, - { - "ip": "211.171.32.146", - "port": 9935 - }, - { - "ip": "211.184.113.145", - "port": 80 - }, - { - "ip": "211.184.113.145", - "port": 443 - }, - { - "ip": "211.184.113.145", - "port": 3388 - }, - { - "ip": "211.184.113.145", - "port": 4524 - }, - { - "ip": "211.184.113.145", - "port": 5000 - }, - { - "ip": "211.184.113.145", - "port": 6405 - }, - { - "ip": "211.184.113.145", - "port": 36523 - }, - { - "ip": "210.210.178.123", - "port": 142 - }, - { - "ip": "210.210.178.123", - "port": 144 - }, - { - "ip": "210.210.178.123", - "port": 146 - }, - { - "ip": "210.210.178.123", - "port": 148 - }, - { - "ip": "210.210.178.123", - "port": 155 - }, - { - "ip": "210.210.178.123", - "port": 156 - }, - { - "ip": "210.210.178.123", - "port": 443 - }, - { - "ip": "210.210.178.123", - "port": 1500 - }, - { - "ip": "210.210.178.123", - "port": 4040 - }, - { - "ip": "210.210.178.123", - "port": 4043 - }, - { - "ip": "210.210.178.123", - "port": 5000 - }, - { - "ip": "210.210.178.123", - "port": 7777 - }, - { - "ip": "210.210.178.123", - "port": 8082 - }, - { - "ip": "210.210.178.123", - "port": 15000 - }, - { - "ip": "52.201.127.54", - "port": 80 - }, - { - "ip": "52.201.127.54", - "port": 443 - }, - { - "ip": "34.219.130.46", - "port": 8080 - }, - { - "ip": "45.76.101.81", - "port": 80 - }, - { - "ip": "45.76.101.81", - "port": 4001 - }, - { - "ip": "45.76.101.81", - "port": 4002 - }, - { - "ip": "45.76.101.81", - "port": 4003 - }, - { - "ip": "45.76.101.81", - "port": 4007 - }, - { - "ip": "51.178.84.198", - "port": 80 - }, - { - "ip": "51.178.84.198", - "port": 81 - }, - { - "ip": "51.178.84.198", - "port": 443 - }, - { - "ip": "51.178.84.198", - "port": 444 - }, - { - "ip": "51.178.84.198", - "port": 4000 - }, - { - "ip": "51.178.84.198", - "port": 5000 - }, - { - "ip": "51.178.84.198", - "port": 8080 - }, - { - "ip": "52.14.99.68", - "port": 3000 - }, - { - "ip": "54.169.100.112", - "port": 8080 - }, - { - "ip": "54.169.100.112", - "port": 8443 - }, - { - "ip": "54.169.100.112", - "port": 8889 - }, - { - "ip": "104.199.255.76", - "port": 80 - }, - { - "ip": "104.199.255.76", - "port": 443 - }, - { - "ip": "104.199.255.76", - "port": 8083 - }, - { - "ip": "104.199.255.76", - "port": 8084 - }, - { - "ip": "104.199.255.76", - "port": 8085 - }, - { - "ip": "104.199.255.76", - "port": 8090 - }, - { - "ip": "113.198.141.200", - "port": 84 - }, - { - "ip": "113.198.141.200", - "port": 8080 - }, - { - "ip": "113.198.141.200", - "port": 9935 - }, - { - "ip": "185.206.215.185", - "port": 3000 - }, - { - "ip": "185.206.215.185", - "port": 3001 - }, - { - "ip": "185.206.215.185", - "port": 3002 - }, - { - "ip": "185.206.215.185", - "port": 4001 - }, - { - "ip": "211.208.105.122", - "port": 80 - }, - { - "ip": "211.208.105.122", - "port": 81 - }, - { - "ip": "211.208.105.122", - "port": 84 - }, - { - "ip": "211.208.105.122", - "port": 443 - }, - { - "ip": "211.208.105.122", - "port": 8080 - }, - { - "ip": "211.208.105.122", - "port": 9935 - }, - { - "ip": "213.252.245.72", - "port": 30080 - }, - { - "ip": "3.95.227.241", - "port": 80 - }, - { - "ip": "3.95.227.241", - "port": 443 - }, - { - "ip": "52.6.240.247", - "port": 80 - }, - { - "ip": "52.6.240.247", - "port": 443 - }, - { - "ip": "104.248.22.84", - "port": 80 - }, - { - "ip": "104.248.22.84", - "port": 443 - }, - { - "ip": "104.248.22.84", - "port": 8000 - }, - { - "ip": "5.78.40.231", - "port": 80 - }, - { - "ip": "5.78.40.231", - "port": 443 - }, - { - "ip": "5.78.40.231", - "port": 3000 - }, - { - "ip": "5.78.40.231", - "port": 8080 - }, - { - "ip": "34.201.10.197", - "port": 80 - }, - { - "ip": "34.201.10.197", - "port": 8080 - }, - { - "ip": "40.68.150.101", - "port": 80 - }, - { - "ip": "40.68.150.101", - "port": 443 - }, - { - "ip": "40.68.150.101", - "port": 8081 - }, - { - "ip": "168.119.104.1", - "port": 80 - }, - { - "ip": "168.119.104.1", - "port": 443 - }, - { - "ip": "168.119.104.1", - "port": 5601 - }, - { - "ip": "168.119.104.1", - "port": 8080 - }, - { - "ip": "221.158.9.210", - "port": 80 - }, - { - "ip": "221.158.9.210", - "port": 84 - }, - { - "ip": "221.158.9.210", - "port": 6500 - }, - { - "ip": "221.158.9.210", - "port": 8080 - }, - { - "ip": "221.158.9.210", - "port": 8090 - }, - { - "ip": "54.205.27.78", - "port": 80 - }, - { - "ip": "54.205.27.78", - "port": 443 - }, - { - "ip": "134.122.122.203", - "port": 80 - }, - { - "ip": "134.122.122.203", - "port": 443 - }, - { - "ip": "134.122.122.203", - "port": 8080 - }, - { - "ip": "3.104.136.236", - "port": 80 - }, - { - "ip": "3.104.136.236", - "port": 443 - }, - { - "ip": "18.208.123.6", - "port": 80 - }, - { - "ip": "18.208.123.6", - "port": 443 - }, - { - "ip": "212.227.37.159", - "port": 80 - }, - { - "ip": "212.227.37.159", - "port": 443 - }, - { - "ip": "212.227.37.159", - "port": 8080 - }, - { - "ip": "195.225.208.204", - "port": 80 - }, - { - "ip": "195.225.208.204", - "port": 443 - }, - { - "ip": "195.225.208.204", - "port": 8080 - }, - { - "ip": "195.225.208.204", - "port": 8081 - }, - { - "ip": "195.225.208.204", - "port": 8172 - }, - { - "ip": "13.49.92.177", - "port": 80 - }, - { - "ip": "13.49.92.177", - "port": 443 - }, - { - "ip": "3.16.217.58", - "port": 80 - }, - { - "ip": "3.16.217.58", - "port": 443 - }, - { - "ip": "3.16.217.58", - "port": 8080 - }, - { - "ip": "3.16.217.58", - "port": 8081 - }, - { - "ip": "3.16.217.58", - "port": 8085 - }, - { - "ip": "3.16.217.58", - "port": 8090 - }, - { - "ip": "3.16.217.58", - "port": 8443 - }, - { - "ip": "64.225.49.117", - "port": 80 - }, - { - "ip": "64.225.49.117", - "port": 443 - }, - { - "ip": "64.225.49.117", - "port": 3333 - }, - { - "ip": "188.166.91.95", - "port": 80 - }, - { - "ip": "188.166.91.95", - "port": 443 - }, - { - "ip": "188.166.91.95", - "port": 8080 - }, - { - "ip": "46.101.91.154", - "port": 80 - }, - { - "ip": "46.101.91.154", - "port": 443 - }, - { - "ip": "46.101.91.154", - "port": 8080 - }, - { - "ip": "134.122.1.206", - "port": 80 - }, - { - "ip": "134.122.1.206", - "port": 443 - }, - { - "ip": "134.122.1.206", - "port": 8001 - }, - { - "ip": "134.122.1.206", - "port": 9000 - }, - { - "ip": "3.223.193.126", - "port": 80 - }, - { - "ip": "5.161.181.140", - "port": 80 - }, - { - "ip": "5.161.181.140", - "port": 5000 - }, - { - "ip": "13.58.17.165", - "port": 80 - }, - { - "ip": "18.197.228.244", - "port": 8080 - }, - { - "ip": "34.254.180.234", - "port": 8080 - }, - { - "ip": "34.254.180.234", - "port": 8090 - }, - { - "ip": "54.174.110.136", - "port": 80 - }, - { - "ip": "54.174.110.136", - "port": 443 - }, - { - "ip": "54.174.110.136", - "port": 3000 - }, - { - "ip": "54.174.110.136", - "port": 5000 - }, - { - "ip": "54.174.110.136", - "port": 5001 - }, - { - "ip": "54.174.110.136", - "port": 8080 - }, - { - "ip": "54.174.110.136", - "port": 32400 - }, - { - "ip": "112.220.71.250", - "port": 81 - }, - { - "ip": "112.220.71.250", - "port": 84 - }, - { - "ip": "112.220.71.250", - "port": 443 - }, - { - "ip": "112.220.71.250", - "port": 8080 - }, - { - "ip": "112.220.71.250", - "port": 9935 - }, - { - "ip": "144.91.127.139", - "port": 80 - }, - { - "ip": "144.91.127.139", - "port": 443 - }, - { - "ip": "144.91.127.139", - "port": 9090 - }, - { - "ip": "144.91.127.139", - "port": 10000 - }, - { - "ip": "182.92.71.131", - "port": 80 - }, - { - "ip": "182.92.71.131", - "port": 443 - }, - { - "ip": "3.110.39.229", - "port": 80 - }, - { - "ip": "3.110.39.229", - "port": 443 - }, - { - "ip": "3.110.39.229", - "port": 8000 - }, - { - "ip": "3.110.39.229", - "port": 8080 - }, - { - "ip": "3.134.163.77", - "port": 80 - }, - { - "ip": "3.134.163.77", - "port": 443 - }, - { - "ip": "3.134.163.77", - "port": 8080 - }, - { - "ip": "15.228.158.58", - "port": 4000 - }, - { - "ip": "15.228.158.58", - "port": 6000 - }, - { - "ip": "15.228.158.58", - "port": 6050 - }, - { - "ip": "15.228.158.58", - "port": 7000 - }, - { - "ip": "15.228.158.58", - "port": 7050 - }, - { - "ip": "15.228.158.58", - "port": 7500 - }, - { - "ip": "15.228.158.58", - "port": 7777 - }, - { - "ip": "15.228.158.58", - "port": 8000 - }, - { - "ip": "15.228.158.58", - "port": 8001 - }, - { - "ip": "15.228.158.58", - "port": 8050 - }, - { - "ip": "15.228.158.58", - "port": 8700 - }, - { - "ip": "15.228.158.58", - "port": 8893 - }, - { - "ip": "15.228.158.58", - "port": 9001 - }, - { - "ip": "15.228.158.58", - "port": 9005 - }, - { - "ip": "15.228.158.58", - "port": 9006 - }, - { - "ip": "15.228.158.58", - "port": 9008 - }, - { - "ip": "15.228.158.58", - "port": 9010 - }, - { - "ip": "15.228.158.58", - "port": 9011 - }, - { - "ip": "15.228.158.58", - "port": 9012 - }, - { - "ip": "15.228.158.58", - "port": 9999 - }, - { - "ip": "15.228.158.58", - "port": 30000 - }, - { - "ip": "18.140.226.52", - "port": 80 - }, - { - "ip": "18.140.226.52", - "port": 443 - }, - { - "ip": "18.140.226.52", - "port": 4000 - }, - { - "ip": "43.135.76.33", - "port": 80 - }, - { - "ip": "43.135.76.33", - "port": 443 - }, - { - "ip": "43.135.76.33", - "port": 888 - }, - { - "ip": "43.135.76.33", - "port": 1200 - }, - { - "ip": "43.135.76.33", - "port": 3001 - }, - { - "ip": "43.135.76.33", - "port": 5000 - }, - { - "ip": "43.135.76.33", - "port": 5244 - }, - { - "ip": "43.135.76.33", - "port": 8002 - }, - { - "ip": "43.135.76.33", - "port": 8008 - }, - { - "ip": "43.135.76.33", - "port": 9080 - }, - { - "ip": "43.135.76.33", - "port": 13000 - }, - { - "ip": "43.135.76.33", - "port": 23333 - }, - { - "ip": "43.135.76.33", - "port": 25500 - }, - { - "ip": "43.135.76.33", - "port": 31200 - }, - { - "ip": "43.135.76.33", - "port": 36543 - }, - { - "ip": "43.135.76.33", - "port": 38080 - }, - { - "ip": "45.77.32.202", - "port": 80 - }, - { - "ip": "45.77.32.202", - "port": 443 - }, - { - "ip": "45.77.32.202", - "port": 3000 - }, - { - "ip": "45.77.32.202", - "port": 3001 - }, - { - "ip": "45.77.32.202", - "port": 4000 - }, - { - "ip": "45.77.32.202", - "port": 8080 - }, - { - "ip": "54.157.48.167", - "port": 80 - }, - { - "ip": "54.157.48.167", - "port": 443 - }, - { - "ip": "54.157.48.167", - "port": 5000 - }, - { - "ip": "54.157.48.167", - "port": 8080 - }, - { - "ip": "59.16.209.232", - "port": 84 - }, - { - "ip": "59.16.209.232", - "port": 8080 - }, - { - "ip": "74.208.194.251", - "port": 80 - }, - { - "ip": "74.208.194.251", - "port": 443 - }, - { - "ip": "74.208.194.251", - "port": 2001 - }, - { - "ip": "74.208.194.251", - "port": 3001 - }, - { - "ip": "74.208.194.251", - "port": 7000 - }, - { - "ip": "74.208.194.251", - "port": 8001 - }, - { - "ip": "74.208.194.251", - "port": 8002 - }, - { - "ip": "74.208.194.251", - "port": 8006 - }, - { - "ip": "74.208.194.251", - "port": 8007 - }, - { - "ip": "74.208.194.251", - "port": 8080 - }, - { - "ip": "74.208.194.251", - "port": 9000 - }, - { - "ip": "74.208.194.251", - "port": 9001 - }, - { - "ip": "104.248.98.96", - "port": 80 - }, - { - "ip": "104.248.98.96", - "port": 443 - }, - { - "ip": "104.248.98.96", - "port": 805 - }, - { - "ip": "104.248.98.96", - "port": 1899 - }, - { - "ip": "104.248.98.96", - "port": 3128 - }, - { - "ip": "104.248.98.96", - "port": 4435 - }, - { - "ip": "104.248.98.96", - "port": 8080 - }, - { - "ip": "104.248.98.96", - "port": 8881 - }, - { - "ip": "104.248.98.96", - "port": 8888 - }, - { - "ip": "104.248.98.96", - "port": 9001 - }, - { - "ip": "185.130.105.16", - "port": 5000 - }, - { - "ip": "185.130.105.16", - "port": 7000 - }, - { - "ip": "185.130.105.16", - "port": 8080 - }, - { - "ip": "185.130.105.16", - "port": 8083 - }, - { - "ip": "185.130.105.16", - "port": 9100 - }, - { - "ip": "188.138.123.24", - "port": 80 - }, - { - "ip": "188.138.123.24", - "port": 443 - }, - { - "ip": "188.138.123.24", - "port": 5990 - }, - { - "ip": "188.138.123.24", - "port": 5991 - }, - { - "ip": "188.138.123.24", - "port": 5996 - }, - { - "ip": "188.138.123.24", - "port": 8082 - }, - { - "ip": "1.13.5.131", - "port": 3001 - }, - { - "ip": "1.13.5.131", - "port": 5985 - }, - { - "ip": "1.13.5.131", - "port": 47001 - }, - { - "ip": "13.58.118.17", - "port": 8080 - }, - { - "ip": "18.118.25.177", - "port": 80 - }, - { - "ip": "18.118.25.177", - "port": 8080 - }, - { - "ip": "61.34.111.2", - "port": 84 - }, - { - "ip": "61.34.111.2", - "port": 443 - }, - { - "ip": "61.34.111.2", - "port": 8080 - }, - { - "ip": "119.195.193.112", - "port": 80 - }, - { - "ip": "119.195.193.112", - "port": 443 - }, - { - "ip": "119.195.193.112", - "port": 5000 - }, - { - "ip": "119.195.193.112", - "port": 5920 - }, - { - "ip": "119.195.193.112", - "port": 8081 - }, - { - "ip": "165.227.8.244", - "port": 80 - }, - { - "ip": "165.227.8.244", - "port": 443 - }, - { - "ip": "165.227.8.244", - "port": 9320 - }, - { - "ip": "165.227.129.237", - "port": 80 - }, - { - "ip": "165.227.129.237", - "port": 443 - }, - { - "ip": "165.227.129.237", - "port": 8080 - }, - { - "ip": "165.227.129.237", - "port": 15672 - }, - { - "ip": "165.227.129.237", - "port": 22222 - }, - { - "ip": "194.163.164.9", - "port": 80 - }, - { - "ip": "194.163.164.9", - "port": 443 - }, - { - "ip": "194.163.164.9", - "port": 3000 - }, - { - "ip": "194.163.164.9", - "port": 3001 - }, - { - "ip": "194.163.164.9", - "port": 4502 - }, - { - "ip": "194.163.164.9", - "port": 8080 - }, - { - "ip": "35.224.47.226", - "port": 80 - }, - { - "ip": "35.224.47.226", - "port": 443 - }, - { - "ip": "35.224.47.226", - "port": 8080 - }, - { - "ip": "3.14.104.67", - "port": 80 - }, - { - "ip": "14.51.110.213", - "port": 80 - }, - { - "ip": "14.51.110.213", - "port": 81 - }, - { - "ip": "14.51.110.213", - "port": 84 - }, - { - "ip": "14.51.110.213", - "port": 443 - }, - { - "ip": "14.51.110.213", - "port": 8080 - }, - { - "ip": "14.51.110.213", - "port": 9935 - }, - { - "ip": "44.193.50.15", - "port": 3001 - }, - { - "ip": "44.193.50.15", - "port": 8080 - }, - { - "ip": "45.79.152.250", - "port": 80 - }, - { - "ip": "45.79.152.250", - "port": 443 - }, - { - "ip": "45.79.152.250", - "port": 4653 - }, - { - "ip": "45.79.152.250", - "port": 55001 - }, - { - "ip": "54.158.0.195", - "port": 80 - }, - { - "ip": "54.158.0.195", - "port": 8080 - }, - { - "ip": "82.66.47.174", - "port": 80 - }, - { - "ip": "82.66.47.174", - "port": 443 - }, - { - "ip": "82.66.47.174", - "port": 3170 - }, - { - "ip": "82.66.47.174", - "port": 3240 - }, - { - "ip": "82.66.47.174", - "port": 8050 - }, - { - "ip": "82.66.47.174", - "port": 9091 - }, - { - "ip": "82.66.47.174", - "port": 18080 - }, - { - "ip": "82.66.47.174", - "port": 50000 - }, - { - "ip": "125.132.183.14", - "port": 80 - }, - { - "ip": "125.132.183.14", - "port": 84 - }, - { - "ip": "125.132.183.14", - "port": 8080 - }, - { - "ip": "125.132.183.14", - "port": 9935 - }, - { - "ip": "192.81.217.249", - "port": 80 - }, - { - "ip": "192.81.217.249", - "port": 443 - }, - { - "ip": "192.81.217.249", - "port": 3001 - }, - { - "ip": "192.81.217.249", - "port": 3002 - }, - { - "ip": "192.81.217.249", - "port": 3333 - }, - { - "ip": "192.81.217.249", - "port": 3838 - }, - { - "ip": "192.81.217.249", - "port": 7676 - }, - { - "ip": "192.81.217.249", - "port": 16124 - }, - { - "ip": "192.81.217.249", - "port": 26124 - }, - { - "ip": "220.89.240.66", - "port": 80 - }, - { - "ip": "220.89.240.66", - "port": 84 - }, - { - "ip": "220.89.240.66", - "port": 443 - }, - { - "ip": "220.89.240.66", - "port": 8080 - }, - { - "ip": "220.89.240.66", - "port": 9935 - }, - { - "ip": "89.22.114.39", - "port": 5000 - }, - { - "ip": "89.22.114.39", - "port": 7000 - }, - { - "ip": "89.22.114.39", - "port": 7200 - }, - { - "ip": "89.22.114.39", - "port": 10080 - }, - { - "ip": "208.52.191.109", - "port": 7000 - }, - { - "ip": "208.52.191.109", - "port": 7200 - }, - { - "ip": "54.145.167.179", - "port": 80 - }, - { - "ip": "54.145.167.179", - "port": 8045 - }, - { - "ip": "54.145.167.179", - "port": 8443 - }, - { - "ip": "34.149.237.85", - "port": 80 - }, - { - "ip": "34.149.237.85", - "port": 443 - }, - { - "ip": "54.185.132.143", - "port": 80 - }, - { - "ip": "54.185.132.143", - "port": 443 - }, - { - "ip": "54.185.132.143", - "port": 554 - }, - { - "ip": "54.185.132.143", - "port": 555 - }, - { - "ip": "46.226.105.17", - "port": 80 - }, - { - "ip": "46.226.105.17", - "port": 443 - }, - { - "ip": "46.226.105.17", - "port": 7788 - }, - { - "ip": "47.75.97.125", - "port": 80 - }, - { - "ip": "47.75.97.125", - "port": 443 - }, - { - "ip": "47.75.97.125", - "port": 9527 - }, - { - "ip": "47.75.97.125", - "port": 9988 - }, - { - "ip": "51.15.242.225", - "port": 80 - }, - { - "ip": "51.15.242.225", - "port": 443 - }, - { - "ip": "51.15.242.225", - "port": 8080 - }, - { - "ip": "185.209.163.5", - "port": 5000 - }, - { - "ip": "185.209.163.5", - "port": 7000 - }, - { - "ip": "185.209.163.5", - "port": 7200 - }, - { - "ip": "185.209.163.5", - "port": 8080 - }, - { - "ip": "185.209.163.5", - "port": 8083 - }, - { - "ip": "185.209.163.5", - "port": 9100 - }, - { - "ip": "185.209.163.5", - "port": 25080 - }, - { - "ip": "5.189.131.174", - "port": 80 - }, - { - "ip": "5.189.131.174", - "port": 8443 - }, - { - "ip": "44.225.81.28", - "port": 80 - }, - { - "ip": "44.225.81.28", - "port": 443 - }, - { - "ip": "44.225.81.28", - "port": 8080 - }, - { - "ip": "51.75.242.226", - "port": 80 - }, - { - "ip": "51.75.242.226", - "port": 8080 - }, - { - "ip": "93.90.200.21", - "port": 80 - }, - { - "ip": "93.90.200.21", - "port": 443 - }, - { - "ip": "93.90.200.21", - "port": 3000 - }, - { - "ip": "93.90.200.21", - "port": 3004 - }, - { - "ip": "93.90.200.21", - "port": 8080 - }, - { - "ip": "93.90.200.21", - "port": 8484 - }, - { - "ip": "93.90.200.21", - "port": 9898 - }, - { - "ip": "152.89.239.157", - "port": 80 - }, - { - "ip": "152.89.239.157", - "port": 443 - }, - { - "ip": "152.89.239.157", - "port": 5000 - }, - { - "ip": "152.89.239.157", - "port": 8080 - }, - { - "ip": "188.166.239.190", - "port": 80 - }, - { - "ip": "188.166.239.190", - "port": 81 - }, - { - "ip": "188.166.239.190", - "port": 3013 - }, - { - "ip": "188.166.239.190", - "port": 8080 - }, - { - "ip": "188.166.239.190", - "port": 8585 - }, - { - "ip": "188.166.239.190", - "port": 8686 - }, - { - "ip": "211.196.39.153", - "port": 80 - }, - { - "ip": "211.196.39.153", - "port": 84 - }, - { - "ip": "211.196.39.153", - "port": 8080 - }, - { - "ip": "211.196.39.153", - "port": 9935 - }, - { - "ip": "211.222.109.92", - "port": 84 - }, - { - "ip": "211.222.109.92", - "port": 443 - }, - { - "ip": "211.222.109.92", - "port": 8080 - }, - { - "ip": "211.222.109.92", - "port": 9935 - }, - { - "ip": "222.99.197.254", - "port": 84 - }, - { - "ip": "222.99.197.254", - "port": 443 - }, - { - "ip": "222.99.197.254", - "port": 8080 - }, - { - "ip": "222.99.197.254", - "port": 9935 - }, - { - "ip": "35.155.126.136", - "port": 80 - }, - { - "ip": "35.155.126.136", - "port": 443 - }, - { - "ip": "54.161.150.126", - "port": 80 - }, - { - "ip": "54.161.150.126", - "port": 443 - }, - { - "ip": "54.232.8.136", - "port": 443 - }, - { - "ip": "54.232.8.136", - "port": 4001 - }, - { - "ip": "54.232.8.136", - "port": 6000 - }, - { - "ip": "54.232.8.136", - "port": 7001 - }, - { - "ip": "54.232.8.136", - "port": 7002 - }, - { - "ip": "54.232.8.136", - "port": 7500 - }, - { - "ip": "54.232.8.136", - "port": 8000 - }, - { - "ip": "54.232.8.136", - "port": 8002 - }, - { - "ip": "54.232.8.136", - "port": 8003 - }, - { - "ip": "54.232.8.136", - "port": 8010 - }, - { - "ip": "54.232.8.136", - "port": 8050 - }, - { - "ip": "54.232.8.136", - "port": 8700 - }, - { - "ip": "54.232.8.136", - "port": 8888 - }, - { - "ip": "54.232.8.136", - "port": 9001 - }, - { - "ip": "54.232.8.136", - "port": 9005 - }, - { - "ip": "54.232.8.136", - "port": 9006 - }, - { - "ip": "54.232.8.136", - "port": 9007 - }, - { - "ip": "54.232.8.136", - "port": 9008 - }, - { - "ip": "54.232.8.136", - "port": 9010 - }, - { - "ip": "54.232.8.136", - "port": 9011 - }, - { - "ip": "54.232.8.136", - "port": 9999 - }, - { - "ip": "54.232.8.136", - "port": 30000 - }, - { - "ip": "211.24.100.197", - "port": 8080 - }, - { - "ip": "211.24.100.197", - "port": 8081 - }, - { - "ip": "211.24.100.197", - "port": 8082 - }, - { - "ip": "211.24.100.197", - "port": 8888 - }, - { - "ip": "211.24.100.197", - "port": 9090 - }, - { - "ip": "23.111.183.102", - "port": 80 - }, - { - "ip": "23.111.183.102", - "port": 5985 - }, - { - "ip": "23.111.183.102", - "port": 8080 - }, - { - "ip": "82.64.203.213", - "port": 80 - }, - { - "ip": "82.64.203.213", - "port": 134 - }, - { - "ip": "82.64.203.213", - "port": 8080 - }, - { - "ip": "82.64.203.213", - "port": 30109 - }, - { - "ip": "54.158.80.14", - "port": 80 - }, - { - "ip": "54.158.80.14", - "port": 443 - }, - { - "ip": "87.242.121.203", - "port": 80 - }, - { - "ip": "87.242.121.203", - "port": 443 - }, - { - "ip": "87.242.121.203", - "port": 3000 - }, - { - "ip": "87.242.121.203", - "port": 4443 - }, - { - "ip": "87.242.121.203", - "port": 5000 - }, - { - "ip": "87.242.121.203", - "port": 7000 - }, - { - "ip": "87.242.121.203", - "port": 8080 - }, - { - "ip": "87.242.121.203", - "port": 8081 - }, - { - "ip": "87.242.121.203", - "port": 8989 - }, - { - "ip": "87.242.121.203", - "port": 9090 - }, - { - "ip": "35.82.65.168", - "port": 80 - }, - { - "ip": "35.82.65.168", - "port": 443 - }, - { - "ip": "64.227.117.99", - "port": 80 - }, - { - "ip": "64.227.117.99", - "port": 443 - }, - { - "ip": "64.227.117.99", - "port": 8080 - }, - { - "ip": "120.92.149.151", - "port": 80 - }, - { - "ip": "120.92.149.151", - "port": 443 - }, - { - "ip": "120.92.149.151", - "port": 19999 - }, - { - "ip": "23.21.207.71", - "port": 80 - }, - { - "ip": "23.21.207.71", - "port": 443 - }, - { - "ip": "34.122.87.123", - "port": 80 - }, - { - "ip": "34.122.87.123", - "port": 8080 - }, - { - "ip": "34.122.87.123", - "port": 8081 - }, - { - "ip": "51.68.139.221", - "port": 80 - }, - { - "ip": "51.68.139.221", - "port": 3001 - }, - { - "ip": "51.68.139.221", - "port": 3002 - }, - { - "ip": "51.68.139.221", - "port": 3003 - }, - { - "ip": "51.68.139.221", - "port": 3010 - }, - { - "ip": "67.205.188.147", - "port": 80 - }, - { - "ip": "67.205.188.147", - "port": 443 - }, - { - "ip": "67.205.188.147", - "port": 1312 - }, - { - "ip": "67.205.188.147", - "port": 8077 - }, - { - "ip": "67.205.188.147", - "port": 11000 - }, - { - "ip": "78.46.223.121", - "port": 80 - }, - { - "ip": "78.46.223.121", - "port": 3000 - }, - { - "ip": "78.46.223.121", - "port": 8080 - }, - { - "ip": "94.183.24.29", - "port": 5985 - }, - { - "ip": "94.183.24.29", - "port": 8080 - }, - { - "ip": "104.237.141.25", - "port": 80 - }, - { - "ip": "104.237.141.25", - "port": 443 - }, - { - "ip": "104.237.141.25", - "port": 3000 - }, - { - "ip": "104.237.141.25", - "port": 8080 - }, - { - "ip": "125.124.29.62", - "port": 80 - }, - { - "ip": "125.124.29.62", - "port": 8080 - }, - { - "ip": "125.124.29.62", - "port": 8081 - }, - { - "ip": "125.124.29.62", - "port": 8090 - }, - { - "ip": "125.124.29.62", - "port": 8888 - }, - { - "ip": "167.71.229.190", - "port": 80 - }, - { - "ip": "167.71.229.190", - "port": 83 - }, - { - "ip": "167.71.229.190", - "port": 85 - }, - { - "ip": "167.71.229.190", - "port": 90 - }, - { - "ip": "167.71.229.190", - "port": 92 - }, - { - "ip": "167.71.229.190", - "port": 3000 - }, - { - "ip": "167.71.229.190", - "port": 5000 - }, - { - "ip": "167.71.229.190", - "port": 8000 - }, - { - "ip": "185.223.95.141", - "port": 80 - }, - { - "ip": "185.223.95.141", - "port": 5000 - }, - { - "ip": "185.223.95.141", - "port": 7000 - }, - { - "ip": "185.223.95.141", - "port": 8080 - }, - { - "ip": "185.223.95.141", - "port": 8083 - }, - { - "ip": "185.223.95.141", - "port": 9100 - }, - { - "ip": "185.223.95.141", - "port": 25080 - }, - { - "ip": "52.42.47.160", - "port": 80 - }, - { - "ip": "52.42.47.160", - "port": 443 - }, - { - "ip": "13.213.61.67", - "port": 5000 - }, - { - "ip": "34.87.69.7", - "port": 80 - }, - { - "ip": "34.87.69.7", - "port": 443 - }, - { - "ip": "34.87.69.7", - "port": 8008 - }, - { - "ip": "34.87.69.7", - "port": 8090 - }, - { - "ip": "52.200.210.238", - "port": 80 - }, - { - "ip": "52.200.210.238", - "port": 443 - }, - { - "ip": "107.21.220.68", - "port": 80 - }, - { - "ip": "133.125.62.169", - "port": 80 - }, - { - "ip": "133.125.62.169", - "port": 6429 - }, - { - "ip": "133.125.62.169", - "port": 7777 - }, - { - "ip": "133.125.62.169", - "port": 33001 - }, - { - "ip": "178.128.199.118", - "port": 80 - }, - { - "ip": "178.128.199.118", - "port": 5000 - }, - { - "ip": "210.206.220.46", - "port": 80 - }, - { - "ip": "210.206.220.46", - "port": 8080 - }, - { - "ip": "210.206.220.46", - "port": 9935 - }, - { - "ip": "217.182.196.20", - "port": 80 - }, - { - "ip": "217.182.196.20", - "port": 443 - }, - { - "ip": "217.182.196.20", - "port": 3000 - }, - { - "ip": "217.182.196.20", - "port": 4323 - }, - { - "ip": "217.182.196.20", - "port": 8080 - }, - { - "ip": "34.111.47.190", - "port": 80 - }, - { - "ip": "34.111.47.190", - "port": 443 - }, - { - "ip": "3.15.84.124", - "port": 8080 - }, - { - "ip": "18.188.65.7", - "port": 80 - }, - { - "ip": "18.188.65.7", - "port": 443 - }, - { - "ip": "18.188.65.7", - "port": 8080 - }, - { - "ip": "18.191.134.97", - "port": 80 - }, - { - "ip": "18.191.134.97", - "port": 1337 - }, - { - "ip": "18.191.134.97", - "port": 3001 - }, - { - "ip": "46.4.59.216", - "port": 80 - }, - { - "ip": "46.4.59.216", - "port": 81 - }, - { - "ip": "46.4.59.216", - "port": 443 - }, - { - "ip": "134.122.8.176", - "port": 80 - }, - { - "ip": "134.122.8.176", - "port": 443 - }, - { - "ip": "134.122.8.176", - "port": 8005 - }, - { - "ip": "134.122.8.176", - "port": 8006 - }, - { - "ip": "134.122.8.176", - "port": 8080 - }, - { - "ip": "134.122.8.176", - "port": 8095 - }, - { - "ip": "134.122.8.176", - "port": 9091 - }, - { - "ip": "134.122.8.176", - "port": 18443 - }, - { - "ip": "134.122.8.176", - "port": 18444 - }, - { - "ip": "141.95.19.7", - "port": 80 - }, - { - "ip": "141.95.19.7", - "port": 8888 - }, - { - "ip": "141.95.19.7", - "port": 12804 - }, - { - "ip": "141.95.19.7", - "port": 14498 - }, - { - "ip": "141.95.19.7", - "port": 21420 - }, - { - "ip": "141.95.19.7", - "port": 54321 - }, - { - "ip": "141.95.19.7", - "port": 58794 - }, - { - "ip": "52.78.213.249", - "port": 80 - }, - { - "ip": "52.78.213.249", - "port": 443 - }, - { - "ip": "46.243.143.202", - "port": 80 - }, - { - "ip": "46.243.143.202", - "port": 443 - }, - { - "ip": "46.243.143.202", - "port": 4000 - }, - { - "ip": "46.243.143.202", - "port": 4443 - }, - { - "ip": "46.243.143.202", - "port": 5000 - }, - { - "ip": "46.243.143.202", - "port": 7000 - }, - { - "ip": "46.243.143.202", - "port": 8080 - }, - { - "ip": "46.243.143.202", - "port": 8081 - }, - { - "ip": "46.243.143.202", - "port": 8989 - }, - { - "ip": "46.243.143.202", - "port": 9090 - }, - { - "ip": "94.139.253.232", - "port": 80 - }, - { - "ip": "94.139.253.232", - "port": 443 - }, - { - "ip": "94.139.253.232", - "port": 4000 - }, - { - "ip": "94.139.253.232", - "port": 4443 - }, - { - "ip": "94.139.253.232", - "port": 5000 - }, - { - "ip": "94.139.253.232", - "port": 7000 - }, - { - "ip": "94.139.253.232", - "port": 8080 - }, - { - "ip": "94.139.253.232", - "port": 8081 - }, - { - "ip": "94.139.253.232", - "port": 8095 - }, - { - "ip": "94.139.253.232", - "port": 8989 - }, - { - "ip": "94.139.253.232", - "port": 9090 - }, - { - "ip": "52.53.226.52", - "port": 80 - }, - { - "ip": "52.53.226.52", - "port": 443 - }, - { - "ip": "52.53.226.52", - "port": 8001 - }, - { - "ip": "52.53.226.52", - "port": 9001 - }, - { - "ip": "103.88.47.200", - "port": 443 - }, - { - "ip": "178.170.197.238", - "port": 80 - }, - { - "ip": "178.170.197.238", - "port": 443 - }, - { - "ip": "178.170.197.238", - "port": 4000 - }, - { - "ip": "178.170.197.238", - "port": 4443 - }, - { - "ip": "178.170.197.238", - "port": 5000 - }, - { - "ip": "178.170.197.238", - "port": 7000 - }, - { - "ip": "178.170.197.238", - "port": 8080 - }, - { - "ip": "178.170.197.238", - "port": 8081 - }, - { - "ip": "178.170.197.238", - "port": 8989 - }, - { - "ip": "178.170.197.238", - "port": 9090 - }, - { - "ip": "78.46.240.152", - "port": 80 - }, - { - "ip": "78.46.240.152", - "port": 443 - }, - { - "ip": "78.46.240.152", - "port": 8080 - }, - { - "ip": "78.46.240.152", - "port": 8443 - }, - { - "ip": "104.248.239.136", - "port": 80 - }, - { - "ip": "104.248.239.136", - "port": 443 - }, - { - "ip": "20.105.198.132", - "port": 80 - }, - { - "ip": "20.105.198.132", - "port": 443 - }, - { - "ip": "20.105.198.132", - "port": 32400 - }, - { - "ip": "20.105.198.132", - "port": 50472 - }, - { - "ip": "54.81.107.214", - "port": 80 - }, - { - "ip": "54.81.107.214", - "port": 443 - }, - { - "ip": "54.93.230.80", - "port": 80 - }, - { - "ip": "54.93.230.80", - "port": 443 - }, - { - "ip": "23.94.122.194", - "port": 80 - }, - { - "ip": "23.94.122.194", - "port": 443 - }, - { - "ip": "23.94.122.194", - "port": 5555 - }, - { - "ip": "23.94.122.194", - "port": 8088 - }, - { - "ip": "54.189.177.232", - "port": 80 - }, - { - "ip": "54.189.177.232", - "port": 443 - }, - { - "ip": "185.223.95.135", - "port": 5000 - }, - { - "ip": "185.223.95.135", - "port": 7000 - }, - { - "ip": "185.223.95.135", - "port": 7200 - }, - { - "ip": "185.223.95.135", - "port": 8080 - }, - { - "ip": "185.223.95.135", - "port": 8083 - }, - { - "ip": "185.223.95.135", - "port": 9100 - }, - { - "ip": "185.223.95.135", - "port": 25080 - }, - { - "ip": "3.8.105.140", - "port": 443 - }, - { - "ip": "3.8.105.140", - "port": 3001 - }, - { - "ip": "3.8.105.140", - "port": 8081 - }, - { - "ip": "35.76.36.245", - "port": 443 - }, - { - "ip": "35.76.36.245", - "port": 9101 - }, - { - "ip": "163.43.28.217", - "port": 8080 - }, - { - "ip": "3.211.205.176", - "port": 80 - }, - { - "ip": "3.211.205.176", - "port": 443 - }, - { - "ip": "3.35.100.160", - "port": 443 - }, - { - "ip": "83.222.9.53", - "port": 80 - }, - { - "ip": "83.222.9.53", - "port": 443 - }, - { - "ip": "83.222.9.53", - "port": 8088 - }, - { - "ip": "164.52.192.134", - "port": 443 - }, - { - "ip": "164.52.192.134", - "port": 8093 - }, - { - "ip": "164.52.192.134", - "port": 8443 - }, - { - "ip": "164.52.192.134", - "port": 8445 - }, - { - "ip": "164.52.192.134", - "port": 8451 - }, - { - "ip": "164.52.192.134", - "port": 8452 - }, - { - "ip": "164.52.192.134", - "port": 8453 - }, - { - "ip": "164.52.192.134", - "port": 8454 - }, - { - "ip": "164.52.192.134", - "port": 8455 - }, - { - "ip": "164.52.192.134", - "port": 8456 - }, - { - "ip": "164.52.192.134", - "port": 8457 - }, - { - "ip": "164.52.192.134", - "port": 8458 - }, - { - "ip": "164.52.192.134", - "port": 8459 - }, - { - "ip": "164.52.192.134", - "port": 8461 - }, - { - "ip": "164.52.192.134", - "port": 8462 - }, - { - "ip": "164.52.192.134", - "port": 8463 - }, - { - "ip": "164.52.192.134", - "port": 8464 - }, - { - "ip": "164.52.192.134", - "port": 8465 - }, - { - "ip": "164.52.192.134", - "port": 8466 - }, - { - "ip": "164.52.192.134", - "port": 8467 - }, - { - "ip": "164.52.192.134", - "port": 8468 - }, - { - "ip": "164.52.192.134", - "port": 8469 - }, - { - "ip": "164.52.192.134", - "port": 42000 - }, - { - "ip": "164.52.192.134", - "port": 42002 - }, - { - "ip": "161.35.70.169", - "port": 80 - }, - { - "ip": "161.35.70.169", - "port": 443 - }, - { - "ip": "161.35.70.169", - "port": 3838 - }, - { - "ip": "3.215.191.178", - "port": 443 - }, - { - "ip": "3.215.191.178", - "port": 943 - }, - { - "ip": "3.215.191.178", - "port": 8080 - }, - { - "ip": "3.215.191.178", - "port": 8081 - }, - { - "ip": "5.161.49.136", - "port": 80 - }, - { - "ip": "5.161.49.136", - "port": 5000 - }, - { - "ip": "13.232.56.239", - "port": 80 - }, - { - "ip": "13.232.56.239", - "port": 443 - }, - { - "ip": "13.232.56.239", - "port": 8080 - }, - { - "ip": "54.74.32.236", - "port": 80 - }, - { - "ip": "54.74.32.236", - "port": 443 - }, - { - "ip": "54.74.32.236", - "port": 8080 - }, - { - "ip": "54.255.69.188", - "port": 80 - }, - { - "ip": "122.177.226.203", - "port": 8080 - }, - { - "ip": "125.138.102.205", - "port": 80 - }, - { - "ip": "125.138.102.205", - "port": 84 - }, - { - "ip": "125.138.102.205", - "port": 8080 - }, - { - "ip": "125.138.102.205", - "port": 9935 - }, - { - "ip": "167.71.130.240", - "port": 9000 - }, - { - "ip": "184.73.88.6", - "port": 3000 - }, - { - "ip": "188.121.116.160", - "port": 80 - }, - { - "ip": "188.121.116.160", - "port": 8080 - }, - { - "ip": "188.121.116.160", - "port": 8081 - }, - { - "ip": "188.121.116.160", - "port": 8406 - }, - { - "ip": "188.121.116.160", - "port": 8413 - }, - { - "ip": "188.121.116.160", - "port": 8418 - }, - { - "ip": "188.121.116.160", - "port": 8420 - }, - { - "ip": "188.121.116.160", - "port": 8421 - }, - { - "ip": "3.34.154.90", - "port": 80 - }, - { - "ip": "3.34.154.90", - "port": 443 - }, - { - "ip": "178.170.242.112", - "port": 80 - }, - { - "ip": "178.170.242.112", - "port": 443 - }, - { - "ip": "178.170.242.112", - "port": 3000 - }, - { - "ip": "178.170.242.112", - "port": 4000 - }, - { - "ip": "178.170.242.112", - "port": 4443 - }, - { - "ip": "178.170.242.112", - "port": 5000 - }, - { - "ip": "178.170.242.112", - "port": 7000 - }, - { - "ip": "178.170.242.112", - "port": 8080 - }, - { - "ip": "178.170.242.112", - "port": 8081 - }, - { - "ip": "178.170.242.112", - "port": 8989 - }, - { - "ip": "178.170.242.112", - "port": 9090 - }, - { - "ip": "18.141.47.134", - "port": 80 - }, - { - "ip": "18.209.193.181", - "port": 80 - }, - { - "ip": "18.209.193.181", - "port": 443 - }, - { - "ip": "18.209.193.181", - "port": 8081 - }, - { - "ip": "34.206.0.36", - "port": 8080 - }, - { - "ip": "34.206.0.36", - "port": 8099 - }, - { - "ip": "34.206.0.36", - "port": 8888 - }, - { - "ip": "34.206.0.36", - "port": 9010 - }, - { - "ip": "37.140.195.68", - "port": 80 - }, - { - "ip": "37.140.195.68", - "port": 443 - }, - { - "ip": "37.140.195.68", - "port": 8080 - }, - { - "ip": "45.7.230.11", - "port": 80 - }, - { - "ip": "45.7.230.11", - "port": 443 - }, - { - "ip": "45.7.230.11", - "port": 3000 - }, - { - "ip": "45.7.230.11", - "port": 3111 - }, - { - "ip": "45.7.230.11", - "port": 3120 - }, - { - "ip": "45.7.230.11", - "port": 3300 - }, - { - "ip": "45.7.230.11", - "port": 3333 - }, - { - "ip": "45.7.230.11", - "port": 3400 - }, - { - "ip": "45.7.230.11", - "port": 4000 - }, - { - "ip": "45.7.230.11", - "port": 5000 - }, - { - "ip": "54.178.164.137", - "port": 8080 - }, - { - "ip": "101.132.100.244", - "port": 80 - }, - { - "ip": "101.132.100.244", - "port": 443 - }, - { - "ip": "101.132.100.244", - "port": 5985 - }, - { - "ip": "101.132.100.244", - "port": 8002 - }, - { - "ip": "101.132.100.244", - "port": 8003 - }, - { - "ip": "101.132.100.244", - "port": 8078 - }, - { - "ip": "101.132.100.244", - "port": 8443 - }, - { - "ip": "101.132.100.244", - "port": 47001 - }, - { - "ip": "122.52.135.214", - "port": 80 - }, - { - "ip": "122.52.135.214", - "port": 443 - }, - { - "ip": "122.52.135.214", - "port": 3000 - }, - { - "ip": "122.52.135.214", - "port": 5357 - }, - { - "ip": "122.52.135.214", - "port": 5985 - }, - { - "ip": "124.25.222.105", - "port": 5000 - }, - { - "ip": "124.25.222.105", - "port": 8080 - }, - { - "ip": "134.209.105.51", - "port": 80 - }, - { - "ip": "134.209.105.51", - "port": 6081 - }, - { - "ip": "134.209.105.51", - "port": 8080 - }, - { - "ip": "162.254.33.70", - "port": 80 - }, - { - "ip": "162.254.33.70", - "port": 90 - }, - { - "ip": "162.254.33.70", - "port": 445 - }, - { - "ip": "162.254.33.70", - "port": 2000 - }, - { - "ip": "162.254.33.70", - "port": 3000 - }, - { - "ip": "162.254.33.70", - "port": 8080 - }, - { - "ip": "185.211.170.118", - "port": 80 - }, - { - "ip": "185.211.170.118", - "port": 443 - }, - { - "ip": "185.211.170.118", - "port": 3005 - }, - { - "ip": "185.211.170.118", - "port": 3006 - }, - { - "ip": "50.83.117.177", - "port": 1000 - }, - { - "ip": "50.83.117.177", - "port": 3000 - }, - { - "ip": "50.83.117.177", - "port": 5555 - }, - { - "ip": "50.83.117.177", - "port": 7010 - }, - { - "ip": "50.83.117.177", - "port": 7082 - }, - { - "ip": "50.83.117.177", - "port": 8028 - }, - { - "ip": "50.83.117.177", - "port": 8088 - }, - { - "ip": "50.83.117.177", - "port": 8123 - }, - { - "ip": "69.231.148.85", - "port": 80 - }, - { - "ip": "69.231.148.85", - "port": 443 - }, - { - "ip": "178.154.209.44", - "port": 80 - }, - { - "ip": "178.154.209.44", - "port": 443 - }, - { - "ip": "178.154.209.44", - "port": 7100 - }, - { - "ip": "178.154.209.44", - "port": 7300 - }, - { - "ip": "178.154.209.44", - "port": 7350 - }, - { - "ip": "178.154.209.44", - "port": 7750 - }, - { - "ip": "178.154.209.44", - "port": 8887 - }, - { - "ip": "178.154.209.44", - "port": 8888 - }, - { - "ip": "178.154.209.44", - "port": 17100 - }, - { - "ip": "178.154.209.44", - "port": 17350 - }, - { - "ip": "178.154.209.44", - "port": 18088 - }, - { - "ip": "178.154.209.44", - "port": 27500 - }, - { - "ip": "162.249.134.222", - "port": 80 - }, - { - "ip": "162.249.134.222", - "port": 443 - }, - { - "ip": "162.249.134.222", - "port": 8080 - }, - { - "ip": "162.249.134.222", - "port": 8443 - }, - { - "ip": "162.249.134.222", - "port": 30005 - }, - { - "ip": "35.162.46.198", - "port": 80 - }, - { - "ip": "35.162.46.198", - "port": 443 - }, - { - "ip": "54.72.32.115", - "port": 80 - }, - { - "ip": "54.72.32.115", - "port": 443 - }, - { - "ip": "159.223.156.168", - "port": 80 - }, - { - "ip": "159.223.156.168", - "port": 443 - }, - { - "ip": "159.223.156.168", - "port": 3000 - }, - { - "ip": "204.48.25.147", - "port": 80 - }, - { - "ip": "204.48.25.147", - "port": 443 - }, - { - "ip": "204.48.25.147", - "port": 8080 - }, - { - "ip": "34.250.32.232", - "port": 80 - }, - { - "ip": "34.250.32.232", - "port": 443 - }, - { - "ip": "34.250.32.232", - "port": 8080 - }, - { - "ip": "35.162.113.11", - "port": 80 - }, - { - "ip": "35.162.113.11", - "port": 443 - }, - { - "ip": "116.203.201.172", - "port": 80 - }, - { - "ip": "116.203.201.172", - "port": 443 - }, - { - "ip": "116.203.201.172", - "port": 8080 - }, - { - "ip": "3.211.136.232", - "port": 80 - }, - { - "ip": "3.211.136.232", - "port": 443 - }, - { - "ip": "15.165.191.58", - "port": 443 - }, - { - "ip": "38.127.12.23", - "port": 80 - }, - { - "ip": "38.127.12.23", - "port": 443 - }, - { - "ip": "38.127.12.23", - "port": 8080 - }, - { - "ip": "38.127.12.23", - "port": 8181 - }, - { - "ip": "38.127.12.23", - "port": 10000 - }, - { - "ip": "140.141.184.38", - "port": 80 - }, - { - "ip": "140.141.184.38", - "port": 443 - }, - { - "ip": "140.141.184.38", - "port": 4000 - }, - { - "ip": "140.141.184.38", - "port": 4001 - }, - { - "ip": "140.141.184.38", - "port": 5000 - }, - { - "ip": "140.141.184.38", - "port": 5600 - }, - { - "ip": "140.141.184.38", - "port": 5601 - }, - { - "ip": "140.141.184.38", - "port": 5902 - }, - { - "ip": "140.141.184.38", - "port": 5904 - }, - { - "ip": "140.141.184.38", - "port": 7200 - }, - { - "ip": "140.141.184.38", - "port": 7201 - }, - { - "ip": "140.141.184.38", - "port": 8080 - }, - { - "ip": "178.170.197.238", - "port": 80 - }, - { - "ip": "178.170.197.238", - "port": 443 - }, - { - "ip": "178.170.197.238", - "port": 4000 - }, - { - "ip": "178.170.197.238", - "port": 4443 - }, - { - "ip": "178.170.197.238", - "port": 5000 - }, - { - "ip": "178.170.197.238", - "port": 7000 - }, - { - "ip": "178.170.197.238", - "port": 8080 - }, - { - "ip": "178.170.197.238", - "port": 8081 - }, - { - "ip": "178.170.197.238", - "port": 8989 - }, - { - "ip": "178.170.197.238", - "port": 9090 - }, - { - "ip": "54.84.85.90", - "port": 80 - }, - { - "ip": "54.84.85.90", - "port": 443 - }, - { - "ip": "3.37.9.17", - "port": 80 - }, - { - "ip": "3.37.9.17", - "port": 443 - }, - { - "ip": "3.125.254.251", - "port": 80 - }, - { - "ip": "3.125.254.251", - "port": 443 - }, - { - "ip": "34.242.193.218", - "port": 443 - }, - { - "ip": "94.130.24.222", - "port": 80 - }, - { - "ip": "94.130.24.222", - "port": 443 - }, - { - "ip": "167.179.168.75", - "port": 80 - }, - { - "ip": "167.179.168.75", - "port": 443 - }, - { - "ip": "178.62.71.7", - "port": 80 - }, - { - "ip": "178.62.71.7", - "port": 443 - }, - { - "ip": "3.8.105.140", - "port": 443 - }, - { - "ip": "3.8.105.140", - "port": 3001 - }, - { - "ip": "3.8.105.140", - "port": 8081 - }, - { - "ip": "35.76.36.245", - "port": 443 - }, - { - "ip": "35.76.36.245", - "port": 9101 - }, - { - "ip": "163.43.28.217", - "port": 8080 - }, - { - "ip": "35.165.157.242", - "port": 8080 - }, - { - "ip": "121.159.147.72", - "port": 80 - }, - { - "ip": "121.159.147.72", - "port": 443 - }, - { - "ip": "121.159.147.72", - "port": 8888 - }, - { - "ip": "198.52.97.135", - "port": 80 - }, - { - "ip": "198.52.97.135", - "port": 443 - }, - { - "ip": "198.52.97.135", - "port": 3000 - }, - { - "ip": "198.52.97.135", - "port": 3001 - }, - { - "ip": "198.52.97.135", - "port": 8011 - }, - { - "ip": "198.52.97.135", - "port": 8090 - }, - { - "ip": "167.235.22.105", - "port": 80 - }, - { - "ip": "167.235.22.105", - "port": 8443 - }, - { - "ip": "50.53.252.164", - "port": 81 - }, - { - "ip": "50.53.252.164", - "port": 8096 - }, - { - "ip": "50.53.252.164", - "port": 9124 - }, - { - "ip": "50.53.252.164", - "port": 47989 - }, - { - "ip": "178.128.73.254", - "port": 80 - }, - { - "ip": "178.128.73.254", - "port": 443 - }, - { - "ip": "178.128.73.254", - "port": 8080 - }, - { - "ip": "13.49.28.40", - "port": 443 - }, - { - "ip": "13.49.28.40", - "port": 444 - }, - { - "ip": "45.77.112.110", - "port": 80 - }, - { - "ip": "45.77.112.110", - "port": 443 - }, - { - "ip": "45.77.112.110", - "port": 8080 - }, - { - "ip": "3.21.37.242", - "port": 80 - }, - { - "ip": "3.21.37.242", - "port": 443 - }, - { - "ip": "3.21.37.242", - "port": 8080 - }, - { - "ip": "91.226.82.5", - "port": 80 - }, - { - "ip": "91.226.82.5", - "port": 443 - }, - { - "ip": "91.226.82.5", - "port": 8010 - }, - { - "ip": "91.226.82.5", - "port": 8020 - }, - { - "ip": "188.166.166.45", - "port": 80 - }, - { - "ip": "188.166.166.45", - "port": 443 - }, - { - "ip": "188.166.166.45", - "port": 8000 - }, - { - "ip": "188.166.166.45", - "port": 8080 - }, - { - "ip": "188.166.166.45", - "port": 9000 - }, - { - "ip": "159.69.45.53", - "port": 80 - }, - { - "ip": "159.69.45.53", - "port": 443 - }, - { - "ip": "159.69.45.53", - "port": 8080 - }, - { - "ip": "35.83.143.0", - "port": 80 - }, - { - "ip": "35.83.143.0", - "port": 443 - }, - { - "ip": "54.252.183.112", - "port": 80 - }, - { - "ip": "54.252.183.112", - "port": 443 - }, - { - "ip": "46.101.119.123", - "port": 80 - }, - { - "ip": "46.101.119.123", - "port": 443 - }, - { - "ip": "46.101.119.123", - "port": 3333 - }, - { - "ip": "95.217.133.207", - "port": 80 - }, - { - "ip": "95.217.133.207", - "port": 443 - }, - { - "ip": "95.217.133.207", - "port": 9100 - }, - { - "ip": "34.120.96.202", - "port": 443 - }, - { - "ip": "65.2.96.227", - "port": 80 - }, - { - "ip": "65.2.96.227", - "port": 443 - }, - { - "ip": "65.2.96.227", - "port": 8080 - }, - { - "ip": "18.167.110.110", - "port": 443 - }, - { - "ip": "44.235.65.3", - "port": 80 - }, - { - "ip": "44.235.65.3", - "port": 443 - }, - { - "ip": "52.208.185.100", - "port": 80 - }, - { - "ip": "52.208.185.100", - "port": 443 - }, - { - "ip": "34.107.154.12", - "port": 80 - }, - { - "ip": "34.107.154.12", - "port": 443 - }, - { - "ip": "54.92.243.20", - "port": 80 - }, - { - "ip": "54.92.243.20", - "port": 443 - }, - { - "ip": "18.143.211.57", - "port": 80 - }, - { - "ip": "18.143.211.57", - "port": 443 - }, - { - "ip": "18.191.201.241", - "port": 80 - }, - { - "ip": "18.191.201.241", - "port": 443 - }, - { - "ip": "87.242.92.183", - "port": 80 - }, - { - "ip": "87.242.92.183", - "port": 443 - }, - { - "ip": "87.242.92.183", - "port": 3000 - }, - { - "ip": "87.242.92.183", - "port": 4000 - }, - { - "ip": "87.242.92.183", - "port": 4443 - }, - { - "ip": "87.242.92.183", - "port": 5000 - }, - { - "ip": "87.242.92.183", - "port": 7000 - }, - { - "ip": "87.242.92.183", - "port": 8080 - }, - { - "ip": "87.242.92.183", - "port": 8081 - }, - { - "ip": "87.242.92.183", - "port": 8989 - }, - { - "ip": "87.242.92.183", - "port": 9090 - }, - { - "ip": "54.148.63.178", - "port": 80 - }, - { - "ip": "54.148.63.178", - "port": 443 - }, - { - "ip": "157.245.192.184", - "port": 80 - }, - { - "ip": "157.245.192.184", - "port": 443 - }, - { - "ip": "157.245.192.184", - "port": 3110 - }, - { - "ip": "157.245.192.184", - "port": 5200 - }, - { - "ip": "157.245.192.184", - "port": 5553 - }, - { - "ip": "157.245.192.184", - "port": 5554 - }, - { - "ip": "157.245.192.184", - "port": 5601 - }, - { - "ip": "157.245.192.184", - "port": 8200 - }, - { - "ip": "157.245.192.184", - "port": 9200 - }, - { - "ip": "161.189.31.64", - "port": 80 - }, - { - "ip": "161.189.31.64", - "port": 443 - }, - { - "ip": "35.180.252.41", - "port": 80 - }, - { - "ip": "35.180.252.41", - "port": 443 - }, - { - "ip": "35.180.252.41", - "port": 8080 - }, - { - "ip": "18.168.194.155", - "port": 443 - }, - { - "ip": "104.248.228.251", - "port": 443 - }, - { - "ip": "212.47.254.65", - "port": 80 - }, - { - "ip": "212.47.254.65", - "port": 443 - }, - { - "ip": "212.47.254.65", - "port": 8081 - }, - { - "ip": "185.197.60.26", - "port": 80 - }, - { - "ip": "185.197.60.26", - "port": 443 - }, - { - "ip": "34.136.231.199", - "port": 1456 - }, - { - "ip": "144.202.50.140", - "port": 443 - }, - { - "ip": "35.195.227.108", - "port": 443 - }, - { - "ip": "35.195.227.108", - "port": 8843 - }, - { - "ip": "39.100.135.198", - "port": 80 - }, - { - "ip": "39.100.135.198", - "port": 8000 - }, - { - "ip": "39.100.135.198", - "port": 8080 - }, - { - "ip": "39.100.135.198", - "port": 9010 - }, - { - "ip": "178.62.9.78", - "port": 80 - }, - { - "ip": "178.62.9.78", - "port": 443 - }, - { - "ip": "178.62.9.78", - "port": 4848 - }, - { - "ip": "178.62.9.78", - "port": 8080 - }, - { - "ip": "178.62.9.78", - "port": 8181 - }, - { - "ip": "178.62.9.78", - "port": 9080 - }, - { - "ip": "54.220.83.78", - "port": 80 - }, - { - "ip": "54.220.83.78", - "port": 443 - }, - { - "ip": "54.220.83.78", - "port": 8080 - }, - { - "ip": "89.221.210.112", - "port": 80 - }, - { - "ip": "89.221.210.112", - "port": 443 - }, - { - "ip": "103.4.14.232", - "port": 443 - }, - { - "ip": "118.195.154.47", - "port": 80 - }, - { - "ip": "118.195.154.47", - "port": 443 - }, - { - "ip": "14.47.193.210", - "port": 80 - }, - { - "ip": "14.47.193.210", - "port": 84 - }, - { - "ip": "14.47.193.210", - "port": 8080 - }, - { - "ip": "14.47.193.210", - "port": 9935 - }, - { - "ip": "15.165.33.140", - "port": 80 - }, - { - "ip": "15.165.33.140", - "port": 443 - }, - { - "ip": "15.165.33.140", - "port": 3000 - }, - { - "ip": "15.165.33.140", - "port": 8081 - }, - { - "ip": "15.207.158.215", - "port": 80 - }, - { - "ip": "35.82.176.44", - "port": 6443 - }, - { - "ip": "35.82.176.44", - "port": 8070 - }, - { - "ip": "35.82.176.44", - "port": 8080 - }, - { - "ip": "35.82.176.44", - "port": 8090 - }, - { - "ip": "47.119.165.157", - "port": 80 - }, - { - "ip": "47.119.165.157", - "port": 443 - }, - { - "ip": "47.119.165.157", - "port": 8080 - }, - { - "ip": "47.119.165.157", - "port": 8081 - }, - { - "ip": "47.119.165.157", - "port": 8088 - }, - { - "ip": "47.119.165.157", - "port": 8100 - }, - { - "ip": "47.119.165.157", - "port": 8560 - }, - { - "ip": "47.119.165.157", - "port": 8808 - }, - { - "ip": "47.119.165.157", - "port": 8848 - }, - { - "ip": "47.119.165.157", - "port": 8881 - }, - { - "ip": "47.119.165.157", - "port": 9999 - }, - { - "ip": "50.116.52.5", - "port": 80 - }, - { - "ip": "50.116.52.5", - "port": 443 - }, - { - "ip": "50.116.52.5", - "port": 8080 - }, - { - "ip": "51.158.64.90", - "port": 443 - }, - { - "ip": "51.158.64.90", - "port": 8005 - }, - { - "ip": "51.158.64.90", - "port": 8801 - }, - { - "ip": "62.171.165.248", - "port": 80 - }, - { - "ip": "62.171.165.248", - "port": 443 - }, - { - "ip": "62.171.165.248", - "port": 4000 - }, - { - "ip": "62.171.165.248", - "port": 5000 - }, - { - "ip": "62.171.165.248", - "port": 8000 - }, - { - "ip": "62.171.165.248", - "port": 8080 - }, - { - "ip": "62.171.165.248", - "port": 8083 - }, - { - "ip": "62.171.165.248", - "port": 8084 - }, - { - "ip": "62.171.165.248", - "port": 8087 - }, - { - "ip": "62.171.165.248", - "port": 8091 - }, - { - "ip": "62.171.165.248", - "port": 9000 - }, - { - "ip": "121.142.156.174", - "port": 80 - }, - { - "ip": "121.142.156.174", - "port": 84 - }, - { - "ip": "121.142.156.174", - "port": 8080 - }, - { - "ip": "121.142.156.174", - "port": 9935 - }, - { - "ip": "129.152.11.248", - "port": 8080 - }, - { - "ip": "185.63.135.46", - "port": 80 - }, - { - "ip": "185.63.135.46", - "port": 443 - }, - { - "ip": "185.63.135.46", - "port": 3000 - }, - { - "ip": "185.63.135.46", - "port": 3001 - }, - { - "ip": "185.63.135.46", - "port": 5000 - }, - { - "ip": "185.63.135.46", - "port": 5005 - }, - { - "ip": "185.63.135.46", - "port": 8080 - }, - { - "ip": "185.242.235.60", - "port": 80 - }, - { - "ip": "185.242.235.60", - "port": 443 - }, - { - "ip": "185.242.235.60", - "port": 5244 - }, - { - "ip": "185.242.235.60", - "port": 5432 - }, - { - "ip": "185.242.235.60", - "port": 8000 - }, - { - "ip": "185.242.235.60", - "port": 9090 - }, - { - "ip": "198.71.49.72", - "port": 80 - }, - { - "ip": "198.71.49.72", - "port": 8080 - }, - { - "ip": "200.89.174.210", - "port": 80 - }, - { - "ip": "200.89.174.210", - "port": 81 - }, - { - "ip": "200.89.174.210", - "port": 8000 - }, - { - "ip": "200.89.174.210", - "port": 8080 - }, - { - "ip": "200.89.174.210", - "port": 8081 - }, - { - "ip": "200.89.174.210", - "port": 9000 - }, - { - "ip": "200.89.174.210", - "port": 9080 - }, - { - "ip": "34.246.248.116", - "port": 80 - }, - { - "ip": "34.246.248.116", - "port": 443 - }, - { - "ip": "54.87.232.204", - "port": 80 - }, - { - "ip": "54.87.232.204", - "port": 443 - }, - { - "ip": "46.38.237.4", - "port": 80 - }, - { - "ip": "46.38.237.4", - "port": 443 - }, - { - "ip": "46.38.237.4", - "port": 1024 - }, - { - "ip": "46.38.237.4", - "port": 3000 - }, - { - "ip": "46.38.237.4", - "port": 3128 - }, - { - "ip": "46.38.237.4", - "port": 4430 - }, - { - "ip": "46.38.237.4", - "port": 4433 - }, - { - "ip": "46.38.237.4", - "port": 8080 - }, - { - "ip": "46.38.237.4", - "port": 8085 - }, - { - "ip": "46.38.237.4", - "port": 8090 - }, - { - "ip": "46.38.237.4", - "port": 8180 - }, - { - "ip": "46.38.237.4", - "port": 9325 - }, - { - "ip": "46.38.237.4", - "port": 9335 - }, - { - "ip": "83.136.219.65", - "port": 80 - }, - { - "ip": "83.136.219.65", - "port": 443 - }, - { - "ip": "83.136.219.65", - "port": 3000 - }, - { - "ip": "18.189.205.130", - "port": 80 - }, - { - "ip": "18.189.205.130", - "port": 443 - }, - { - "ip": "18.189.205.130", - "port": 4001 - }, - { - "ip": "18.189.205.130", - "port": 5000 - }, - { - "ip": "164.92.73.227", - "port": 80 - }, - { - "ip": "164.92.73.227", - "port": 443 - }, - { - "ip": "164.92.73.227", - "port": 5000 - }, - { - "ip": "178.170.194.23", - "port": 80 - }, - { - "ip": "178.170.194.23", - "port": 443 - }, - { - "ip": "178.170.194.23", - "port": 4000 - }, - { - "ip": "178.170.194.23", - "port": 4443 - }, - { - "ip": "178.170.194.23", - "port": 5000 - }, - { - "ip": "178.170.194.23", - "port": 7000 - }, - { - "ip": "178.170.194.23", - "port": 8080 - }, - { - "ip": "178.170.194.23", - "port": 8081 - }, - { - "ip": "178.170.194.23", - "port": 8989 - }, - { - "ip": "178.170.194.23", - "port": 9090 - }, - { - "ip": "160.153.247.25", - "port": 80 - }, - { - "ip": "160.153.247.25", - "port": 443 - }, - { - "ip": "160.153.247.25", - "port": 2077 - }, - { - "ip": "160.153.247.25", - "port": 2078 - }, - { - "ip": "160.153.247.25", - "port": 2082 - }, - { - "ip": "160.153.247.25", - "port": 2083 - }, - { - "ip": "160.153.247.25", - "port": 2086 - }, - { - "ip": "160.153.247.25", - "port": 2087 - }, - { - "ip": "160.153.247.25", - "port": 2091 - }, - { - "ip": "160.153.247.25", - "port": 2095 - }, - { - "ip": "160.153.247.25", - "port": 2096 - }, - { - "ip": "160.153.247.25", - "port": 5000 - }, - { - "ip": "160.153.247.25", - "port": 5001 - }, - { - "ip": "160.153.247.25", - "port": 5011 - }, - { - "ip": "160.153.247.25", - "port": 5017 - }, - { - "ip": "160.153.247.25", - "port": 5019 - }, - { - "ip": "160.153.247.25", - "port": 5022 - }, - { - "ip": "160.153.247.25", - "port": 5023 - }, - { - "ip": "160.153.247.25", - "port": 5024 - }, - { - "ip": "160.153.247.25", - "port": 5028 - }, - { - "ip": "160.153.247.25", - "port": 5029 - }, - { - "ip": "160.153.247.25", - "port": 5050 - }, - { - "ip": "160.153.247.25", - "port": 5100 - }, - { - "ip": "45.79.35.129", - "port": 80 - }, - { - "ip": "45.79.35.129", - "port": 443 - }, - { - "ip": "45.79.35.129", - "port": 8080 - }, - { - "ip": "44.199.44.37", - "port": 80 - }, - { - "ip": "44.199.44.37", - "port": 443 - }, - { - "ip": "46.243.143.30", - "port": 80 - }, - { - "ip": "46.243.143.30", - "port": 443 - }, - { - "ip": "46.243.143.30", - "port": 3000 - }, - { - "ip": "46.243.143.30", - "port": 4000 - }, - { - "ip": "46.243.143.30", - "port": 4443 - }, - { - "ip": "46.243.143.30", - "port": 5000 - }, - { - "ip": "46.243.143.30", - "port": 7000 - }, - { - "ip": "46.243.143.30", - "port": 8080 - }, - { - "ip": "46.243.143.30", - "port": 8081 - }, - { - "ip": "46.243.143.30", - "port": 8989 - }, - { - "ip": "46.243.143.30", - "port": 9090 - }, - { - "ip": "35.174.183.17", - "port": 80 - }, - { - "ip": "35.174.183.17", - "port": 443 - }, - { - "ip": "52.36.8.76", - "port": 443 - }, - { - "ip": "3.64.240.40", - "port": 443 - }, - { - "ip": "87.237.87.107", - "port": 80 - }, - { - "ip": "87.237.87.107", - "port": 443 - }, - { - "ip": "46.4.173.205", - "port": 80 - }, - { - "ip": "46.4.173.205", - "port": 443 - }, - { - "ip": "46.4.173.205", - "port": 2096 - }, - { - "ip": "46.4.173.205", - "port": 3000 - }, - { - "ip": "46.4.173.205", - "port": 3001 - }, - { - "ip": "46.4.173.205", - "port": 3003 - }, - { - "ip": "46.4.173.205", - "port": 4000 - }, - { - "ip": "46.4.173.205", - "port": 4001 - }, - { - "ip": "46.4.173.205", - "port": 7000 - }, - { - "ip": "46.4.173.205", - "port": 7001 - }, - { - "ip": "46.4.173.205", - "port": 7002 - }, - { - "ip": "46.4.173.205", - "port": 8080 - }, - { - "ip": "46.4.173.205", - "port": 8088 - }, - { - "ip": "46.4.173.205", - "port": 8443 - }, - { - "ip": "18.230.165.75", - "port": 80 - }, - { - "ip": "18.230.165.75", - "port": 443 - }, - { - "ip": "18.230.165.75", - "port": 1234 - }, - { - "ip": "18.230.165.75", - "port": 5050 - }, - { - "ip": "18.230.165.75", - "port": 7070 - }, - { - "ip": "34.91.23.92", - "port": 80 - }, - { - "ip": "34.91.23.92", - "port": 443 - }, - { - "ip": "35.158.179.192", - "port": 80 - }, - { - "ip": "35.158.179.192", - "port": 443 - }, - { - "ip": "51.141.38.57", - "port": 443 - }, - { - "ip": "51.141.38.57", - "port": 7443 - }, - { - "ip": "51.141.38.57", - "port": 8188 - }, - { - "ip": "51.141.38.57", - "port": 9110 - }, - { - "ip": "51.141.38.57", - "port": 9120 - }, - { - "ip": "51.141.38.57", - "port": 9130 - }, - { - "ip": "51.141.38.57", - "port": 9140 - }, - { - "ip": "54.178.249.65", - "port": 80 - }, - { - "ip": "54.178.249.65", - "port": 443 - }, - { - "ip": "178.20.42.241", - "port": 443 - }, - { - "ip": "34.134.143.205", - "port": 443 - }, - { - "ip": "103.176.79.252", - "port": 80 - }, - { - "ip": "103.176.79.252", - "port": 443 - }, - { - "ip": "103.176.79.252", - "port": 8080 - }, - { - "ip": "213.32.6.39", - "port": 80 - }, - { - "ip": "213.32.6.39", - "port": 443 - }, - { - "ip": "213.32.6.39", - "port": 6443 - }, - { - "ip": "213.32.6.39", - "port": 8080 - }, - { - "ip": "52.21.87.235", - "port": 80 - }, - { - "ip": "52.21.87.235", - "port": 443 - }, - { - "ip": "13.81.217.56", - "port": 443 - }, - { - "ip": "13.81.217.56", - "port": 5251 - }, - { - "ip": "13.81.217.56", - "port": 8182 - }, - { - "ip": "34.117.181.181", - "port": 443 - }, - { - "ip": "54.225.24.140", - "port": 80 - }, - { - "ip": "54.225.24.140", - "port": 443 - }, - { - "ip": "46.243.201.52", - "port": 80 - }, - { - "ip": "46.243.201.52", - "port": 443 - }, - { - "ip": "46.243.201.52", - "port": 3000 - }, - { - "ip": "46.243.201.52", - "port": 4000 - }, - { - "ip": "46.243.201.52", - "port": 4443 - }, - { - "ip": "46.243.201.52", - "port": 5000 - }, - { - "ip": "46.243.201.52", - "port": 7000 - }, - { - "ip": "46.243.201.52", - "port": 8080 - }, - { - "ip": "46.243.201.52", - "port": 8081 - }, - { - "ip": "46.243.201.52", - "port": 8989 - }, - { - "ip": "46.243.201.52", - "port": 9090 - }, - { - "ip": "149.28.237.160", - "port": 80 - }, - { - "ip": "149.28.237.160", - "port": 443 - }, - { - "ip": "149.28.237.160", - "port": 8080 - }, - { - "ip": "188.72.109.51", - "port": 80 - }, - { - "ip": "188.72.109.51", - "port": 443 - }, - { - "ip": "188.72.109.51", - "port": 3000 - }, - { - "ip": "188.72.109.51", - "port": 4000 - }, - { - "ip": "188.72.109.51", - "port": 4443 - }, - { - "ip": "188.72.109.51", - "port": 5000 - }, - { - "ip": "188.72.109.51", - "port": 7000 - }, - { - "ip": "188.72.109.51", - "port": 8080 - }, - { - "ip": "188.72.109.51", - "port": 8081 - }, - { - "ip": "188.72.109.51", - "port": 8989 - }, - { - "ip": "188.72.109.51", - "port": 9090 - }, - { - "ip": "3.11.160.66", - "port": 443 - }, - { - "ip": "34.77.218.204", - "port": 80 - }, - { - "ip": "34.77.218.204", - "port": 443 - }, - { - "ip": "129.226.225.207", - "port": 80 - }, - { - "ip": "129.226.225.207", - "port": 443 - }, - { - "ip": "129.226.225.207", - "port": 8888 - }, - { - "ip": "139.59.138.119", - "port": 80 - }, - { - "ip": "139.59.138.119", - "port": 443 - }, - { - "ip": "54.225.24.140", - "port": 80 - }, - { - "ip": "54.225.24.140", - "port": 443 - }, - { - "ip": "185.130.105.29", - "port": 5000 - }, - { - "ip": "185.130.105.29", - "port": 7000 - }, - { - "ip": "185.130.105.29", - "port": 7200 - }, - { - "ip": "185.130.105.29", - "port": 8080 - }, - { - "ip": "185.130.105.29", - "port": 8083 - }, - { - "ip": "185.130.105.29", - "port": 9100 - }, - { - "ip": "185.130.105.29", - "port": 25080 - }, - { - "ip": "173.243.226.0", - "port": 443 - }, - { - "ip": "18.159.162.92", - "port": 80 - }, - { - "ip": "18.159.162.92", - "port": 443 - }, - { - "ip": "13.236.213.134", - "port": 80 - }, - { - "ip": "13.236.213.134", - "port": 443 - }, - { - "ip": "34.206.197.141", - "port": 80 - }, - { - "ip": "34.206.197.141", - "port": 443 - }, - { - "ip": "54.166.35.14", - "port": 80 - }, - { - "ip": "54.166.35.14", - "port": 443 - }, - { - "ip": "35.82.89.64", - "port": 443 - }, - { - "ip": "54.246.68.59", - "port": 80 - }, - { - "ip": "54.246.68.59", - "port": 443 - }, - { - "ip": "54.246.68.59", - "port": 3000 - }, - { - "ip": "220.133.106.12", - "port": 80 - }, - { - "ip": "220.133.106.12", - "port": 89 - }, - { - "ip": "220.133.106.12", - "port": 443 - }, - { - "ip": "220.133.106.12", - "port": 3000 - }, - { - "ip": "220.133.106.12", - "port": 3001 - }, - { - "ip": "220.133.106.12", - "port": 3002 - }, - { - "ip": "220.133.106.12", - "port": 3003 - }, - { - "ip": "220.133.106.12", - "port": 3126 - }, - { - "ip": "220.133.106.12", - "port": 5555 - }, - { - "ip": "220.133.106.12", - "port": 8082 - }, - { - "ip": "220.133.106.12", - "port": 8089 - }, - { - "ip": "220.133.106.12", - "port": 8176 - }, - { - "ip": "220.133.106.12", - "port": 8753 - }, - { - "ip": "34.224.217.83", - "port": 80 - }, - { - "ip": "34.224.217.83", - "port": 443 - }, - { - "ip": "52.50.66.13", - "port": 80 - }, - { - "ip": "52.50.66.13", - "port": 443 - }, - { - "ip": "54.237.125.226", - "port": 80 - }, - { - "ip": "54.237.125.226", - "port": 443 - }, - { - "ip": "91.151.16.62", - "port": 80 - }, - { - "ip": "91.151.16.62", - "port": 443 - }, - { - "ip": "91.151.16.62", - "port": 2342 - }, - { - "ip": "91.151.16.62", - "port": 5000 - }, - { - "ip": "18.143.89.39", - "port": 80 - }, - { - "ip": "18.143.89.39", - "port": 443 - }, - { - "ip": "18.143.89.39", - "port": 8080 - }, - { - "ip": "52.18.189.27", - "port": 80 - }, - { - "ip": "52.18.189.27", - "port": 443 - }, - { - "ip": "35.158.26.251", - "port": 80 - }, - { - "ip": "35.158.26.251", - "port": 443 - }, - { - "ip": "35.232.37.58", - "port": 80 - }, - { - "ip": "35.232.37.58", - "port": 443 - }, - { - "ip": "35.232.37.58", - "port": 3000 - }, - { - "ip": "35.232.37.58", - "port": 8080 - }, - { - "ip": "148.72.155.242", - "port": 80 - }, - { - "ip": "148.72.155.242", - "port": 443 - }, - { - "ip": "148.72.155.242", - "port": 3000 - }, - { - "ip": "148.72.155.242", - "port": 8000 - }, - { - "ip": "148.72.155.242", - "port": 9084 - }, - { - "ip": "148.72.155.242", - "port": 9085 - }, - { - "ip": "148.72.155.242", - "port": 9086 - }, - { - "ip": "148.72.155.242", - "port": 9087 - }, - { - "ip": "148.72.155.242", - "port": 9088 - }, - { - "ip": "148.72.155.242", - "port": 9089 - }, - { - "ip": "148.72.155.242", - "port": 9091 - }, - { - "ip": "148.72.155.242", - "port": 9092 - }, - { - "ip": "148.72.155.242", - "port": 9093 - }, - { - "ip": "148.72.155.242", - "port": 9094 - }, - { - "ip": "148.72.155.242", - "port": 9098 - }, - { - "ip": "198.251.78.181", - "port": 80 - }, - { - "ip": "198.251.78.181", - "port": 443 - }, - { - "ip": "198.251.78.181", - "port": 8080 - }, - { - "ip": "198.251.78.181", - "port": 9000 - }, - { - "ip": "159.223.40.242", - "port": 80 - }, - { - "ip": "159.223.40.242", - "port": 443 - }, - { - "ip": "159.223.40.242", - "port": 8080 - }, - { - "ip": "3.93.155.208", - "port": 80 - }, - { - "ip": "3.93.155.208", - "port": 443 - }, - { - "ip": "3.140.56.174", - "port": 80 - }, - { - "ip": "3.140.56.174", - "port": 443 - }, - { - "ip": "35.167.127.39", - "port": 443 - }, - { - "ip": "104.248.146.40", - "port": 80 - }, - { - "ip": "104.248.146.40", - "port": 443 - }, - { - "ip": "104.248.146.40", - "port": 9000 - }, - { - "ip": "104.248.146.40", - "port": 30120 - }, - { - "ip": "195.26.63.43", - "port": 80 - }, - { - "ip": "195.26.63.43", - "port": 443 - }, - { - "ip": "195.26.63.43", - "port": 8070 - }, - { - "ip": "195.26.63.43", - "port": 8809 - }, - { - "ip": "195.26.63.43", - "port": 8845 - }, - { - "ip": "195.26.63.43", - "port": 20001 - }, - { - "ip": "3.213.176.147", - "port": 80 - }, - { - "ip": "3.213.176.147", - "port": 443 - }, - { - "ip": "34.78.168.103", - "port": 80 - }, - { - "ip": "34.78.168.103", - "port": 443 - }, - { - "ip": "34.78.168.103", - "port": 1234 - }, - { - "ip": "34.78.168.103", - "port": 8080 - }, - { - "ip": "45.8.224.229", - "port": 80 - }, - { - "ip": "45.8.224.229", - "port": 443 - }, - { - "ip": "45.8.224.229", - "port": 1337 - }, - { - "ip": "45.8.224.229", - "port": 2077 - }, - { - "ip": "45.8.224.229", - "port": 2078 - }, - { - "ip": "45.8.224.229", - "port": 2082 - }, - { - "ip": "45.8.224.229", - "port": 2083 - }, - { - "ip": "45.8.224.229", - "port": 2086 - }, - { - "ip": "45.8.224.229", - "port": 2087 - }, - { - "ip": "45.8.224.229", - "port": 2091 - }, - { - "ip": "45.8.224.229", - "port": 2095 - }, - { - "ip": "45.8.224.229", - "port": 2096 - }, - { - "ip": "45.8.224.229", - "port": 3000 - }, - { - "ip": "45.8.224.229", - "port": 8080 - }, - { - "ip": "45.8.224.229", - "port": 8081 - }, - { - "ip": "51.91.106.8", - "port": 80 - }, - { - "ip": "51.91.106.8", - "port": 443 - }, - { - "ip": "51.91.106.8", - "port": 1325 - }, - { - "ip": "51.91.106.8", - "port": 5985 - }, - { - "ip": "54.174.34.2", - "port": 80 - }, - { - "ip": "54.174.34.2", - "port": 443 - }, - { - "ip": "31.151.13.253", - "port": 80 - }, - { - "ip": "31.151.13.253", - "port": 443 - }, - { - "ip": "31.151.13.253", - "port": 3000 - }, - { - "ip": "34.212.142.39", - "port": 80 - }, - { - "ip": "34.212.142.39", - "port": 443 - }, - { - "ip": "192.3.253.138", - "port": 80 - }, - { - "ip": "192.3.253.138", - "port": 443 - }, - { - "ip": "192.3.253.138", - "port": 3000 - }, - { - "ip": "192.3.253.138", - "port": 7890 - }, - { - "ip": "192.3.253.138", - "port": 8080 - }, - { - "ip": "192.3.253.138", - "port": 8088 - }, - { - "ip": "89.252.168.180", - "port": 80 - }, - { - "ip": "89.252.168.180", - "port": 443 - }, - { - "ip": "89.252.168.180", - "port": 5985 - }, - { - "ip": "89.252.168.180", - "port": 8443 - }, - { - "ip": "89.252.168.180", - "port": 8880 - }, - { - "ip": "89.252.168.180", - "port": 9000 - }, - { - "ip": "35.164.111.226", - "port": 80 - }, - { - "ip": "35.164.111.226", - "port": 443 - }, - { - "ip": "121.162.229.141", - "port": 80 - }, - { - "ip": "121.162.229.141", - "port": 443 - }, - { - "ip": "121.162.229.141", - "port": 50080 - }, - { - "ip": "121.162.229.141", - "port": 58000 - }, - { - "ip": "138.68.97.30", - "port": 80 - }, - { - "ip": "138.68.97.30", - "port": 443 - }, - { - "ip": "138.68.97.30", - "port": 4005 - }, - { - "ip": "140.126.120.10", - "port": 80 - }, - { - "ip": "140.126.120.10", - "port": 443 - }, - { - "ip": "140.126.120.10", - "port": 8008 - }, - { - "ip": "140.126.120.10", - "port": 8080 - }, - { - "ip": "107.152.47.118", - "port": 80 - }, - { - "ip": "107.152.47.118", - "port": 443 - }, - { - "ip": "107.152.47.118", - "port": 9325 - }, - { - "ip": "107.152.47.118", - "port": 9335 - }, - { - "ip": "18.119.1.57", - "port": 80 - }, - { - "ip": "18.119.1.57", - "port": 443 - }, - { - "ip": "18.119.1.57", - "port": 8080 - }, - { - "ip": "18.135.51.42", - "port": 80 - }, - { - "ip": "18.135.51.42", - "port": 443 - }, - { - "ip": "52.38.210.10", - "port": 443 - }, - { - "ip": "44.215.250.65", - "port": 80 - }, - { - "ip": "44.215.250.65", - "port": 443 - }, - { - "ip": "54.163.9.169", - "port": 443 - }, - { - "ip": "151.236.39.15", - "port": 80 - }, - { - "ip": "151.236.39.15", - "port": 443 - }, - { - "ip": "151.236.39.15", - "port": 3000 - }, - { - "ip": "151.236.39.15", - "port": 7080 - }, - { - "ip": "151.236.39.15", - "port": 7081 - }, - { - "ip": "151.236.39.15", - "port": 8443 - }, - { - "ip": "151.236.39.15", - "port": 8880 - }, - { - "ip": "34.226.72.129", - "port": 80 - }, - { - "ip": "34.226.72.129", - "port": 443 - }, - { - "ip": "18.178.58.170", - "port": 443 - }, - { - "ip": "34.195.86.219", - "port": 80 - }, - { - "ip": "34.195.86.219", - "port": 443 - }, - { - "ip": "34.195.86.219", - "port": 8333 - }, - { - "ip": "209.135.131.13", - "port": 80 - }, - { - "ip": "209.135.131.13", - "port": 443 - }, - { - "ip": "209.135.131.13", - "port": 8000 - }, - { - "ip": "209.135.131.13", - "port": 8001 - }, - { - "ip": "209.135.131.13", - "port": 8008 - }, - { - "ip": "209.135.131.13", - "port": 8010 - }, - { - "ip": "209.135.131.13", - "port": 8011 - }, - { - "ip": "209.135.131.13", - "port": 8080 - }, - { - "ip": "209.135.131.13", - "port": 8100 - }, - { - "ip": "209.135.131.13", - "port": 8443 - }, - { - "ip": "209.135.131.13", - "port": 8700 - }, - { - "ip": "209.135.131.13", - "port": 8701 - }, - { - "ip": "209.135.131.13", - "port": 13100 - }, - { - "ip": "209.135.131.13", - "port": 14200 - }, - { - "ip": "23.21.171.185", - "port": 80 - }, - { - "ip": "23.21.171.185", - "port": 443 - }, - { - "ip": "23.21.171.185", - "port": 8080 - }, - { - "ip": "43.200.89.216", - "port": 443 - }, - { - "ip": "128.199.173.130", - "port": 8080 - }, - { - "ip": "128.199.173.130", - "port": 8085 - }, - { - "ip": "173.243.226.2", - "port": 443 - }, - { - "ip": "200.155.37.210", - "port": 80 - }, - { - "ip": "200.155.37.210", - "port": 443 - }, - { - "ip": "200.155.37.210", - "port": 2740 - }, - { - "ip": "200.155.37.210", - "port": 4433 - }, - { - "ip": "200.155.37.210", - "port": 8004 - }, - { - "ip": "200.155.37.210", - "port": 8080 - }, - { - "ip": "200.155.37.210", - "port": 8081 - }, - { - "ip": "200.155.37.210", - "port": 8082 - }, - { - "ip": "200.155.37.210", - "port": 8089 - }, - { - "ip": "200.155.37.210", - "port": 8092 - }, - { - "ip": "200.155.37.210", - "port": 8180 - }, - { - "ip": "200.155.37.210", - "port": 8282 - }, - { - "ip": "200.155.37.210", - "port": 8383 - }, - { - "ip": "200.155.37.210", - "port": 8443 - }, - { - "ip": "200.155.37.210", - "port": 8444 - }, - { - "ip": "200.155.37.210", - "port": 8445 - }, - { - "ip": "200.155.37.210", - "port": 8885 - }, - { - "ip": "200.155.37.210", - "port": 8887 - }, - { - "ip": "200.155.37.210", - "port": 8888 - }, - { - "ip": "200.155.37.210", - "port": 8889 - }, - { - "ip": "200.155.37.210", - "port": 8990 - }, - { - "ip": "200.155.37.210", - "port": 9898 - }, - { - "ip": "200.155.37.210", - "port": 28080 - }, - { - "ip": "63.32.240.48", - "port": 443 - }, - { - "ip": "103.144.61.54", - "port": 80 - }, - { - "ip": "103.144.61.54", - "port": 3000 - }, - { - "ip": "103.144.61.54", - "port": 8080 - }, - { - "ip": "103.144.61.54", - "port": 8081 - }, - { - "ip": "103.144.61.54", - "port": 8083 - }, - { - "ip": "103.144.61.54", - "port": 8085 - }, - { - "ip": "103.144.61.54", - "port": 8087 - }, - { - "ip": "103.144.61.54", - "port": 8089 - }, - { - "ip": "103.144.61.54", - "port": 8092 - }, - { - "ip": "103.144.61.54", - "port": 8093 - }, - { - "ip": "103.144.61.54", - "port": 8095 - }, - { - "ip": "103.144.61.54", - "port": 8096 - }, - { - "ip": "103.144.61.54", - "port": 8181 - }, - { - "ip": "103.144.61.54", - "port": 8999 - }, - { - "ip": "157.230.225.121", - "port": 80 - }, - { - "ip": "157.230.225.121", - "port": 443 - }, - { - "ip": "157.230.225.121", - "port": 1234 - }, - { - "ip": "93.103.12.150", - "port": 80 - }, - { - "ip": "93.103.12.150", - "port": 85 - }, - { - "ip": "93.103.12.150", - "port": 99 - }, - { - "ip": "93.103.12.150", - "port": 100 - }, - { - "ip": "93.103.12.150", - "port": 102 - }, - { - "ip": "93.103.12.150", - "port": 105 - }, - { - "ip": "93.103.12.150", - "port": 106 - }, - { - "ip": "93.103.12.150", - "port": 443 - }, - { - "ip": "93.103.12.150", - "port": 2443 - }, - { - "ip": "93.103.12.150", - "port": 3000 - }, - { - "ip": "93.103.12.150", - "port": 4080 - }, - { - "ip": "93.103.12.150", - "port": 4081 - }, - { - "ip": "93.103.12.150", - "port": 4082 - }, - { - "ip": "93.103.12.150", - "port": 4083 - }, - { - "ip": "93.103.12.150", - "port": 4085 - }, - { - "ip": "93.103.12.150", - "port": 4183 - }, - { - "ip": "93.103.12.150", - "port": 4284 - }, - { - "ip": "93.103.12.150", - "port": 4285 - }, - { - "ip": "93.103.12.150", - "port": 4286 - }, - { - "ip": "93.103.12.150", - "port": 4343 - }, - { - "ip": "93.103.12.150", - "port": 4388 - }, - { - "ip": "93.103.12.150", - "port": 4396 - }, - { - "ip": "93.103.12.150", - "port": 4399 - }, - { - "ip": "93.103.12.150", - "port": 4400 - }, - { - "ip": "93.103.12.150", - "port": 4401 - }, - { - "ip": "93.103.12.150", - "port": 4402 - }, - { - "ip": "93.103.12.150", - "port": 4403 - }, - { - "ip": "93.103.12.150", - "port": 4406 - }, - { - "ip": "93.103.12.150", - "port": 4408 - }, - { - "ip": "93.103.12.150", - "port": 4409 - }, - { - "ip": "93.103.12.150", - "port": 4411 - }, - { - "ip": "93.103.12.150", - "port": 5000 - }, - { - "ip": "46.18.219.232", - "port": 443 - }, - { - "ip": "46.18.219.232", - "port": 8809 - }, - { - "ip": "46.18.219.232", - "port": 8845 - }, - { - "ip": "52.77.137.121", - "port": 80 - }, - { - "ip": "52.77.137.121", - "port": 443 - }, - { - "ip": "52.77.137.121", - "port": 8080 - }, - { - "ip": "52.77.137.121", - "port": 8686 - }, - { - "ip": "13.42.212.237", - "port": 80 - }, - { - "ip": "13.42.212.237", - "port": 443 - }, - { - "ip": "34.195.171.208", - "port": 80 - }, - { - "ip": "34.195.171.208", - "port": 443 - }, - { - "ip": "54.146.209.210", - "port": 80 - }, - { - "ip": "54.146.209.210", - "port": 443 - }, - { - "ip": "155.138.136.194", - "port": 80 - }, - { - "ip": "155.138.136.194", - "port": 443 - }, - { - "ip": "155.138.136.194", - "port": 5050 - }, - { - "ip": "155.138.136.194", - "port": 5985 - }, - { - "ip": "155.138.136.194", - "port": 9990 - }, - { - "ip": "155.138.136.194", - "port": 9991 - }, - { - "ip": "155.138.136.194", - "port": 9999 - }, - { - "ip": "155.138.136.194", - "port": 47001 - }, - { - "ip": "157.245.131.102", - "port": 80 - }, - { - "ip": "157.245.131.102", - "port": 443 - }, - { - "ip": "18.158.254.32", - "port": 443 - }, - { - "ip": "58.187.24.39", - "port": 81 - }, - { - "ip": "58.187.24.39", - "port": 8443 - }, - { - "ip": "161.35.219.229", - "port": 80 - }, - { - "ip": "161.35.219.229", - "port": 443 - }, - { - "ip": "161.35.219.229", - "port": 8080 - }, - { - "ip": "44.195.218.126", - "port": 80 - }, - { - "ip": "44.195.218.126", - "port": 443 - }, - { - "ip": "3.210.231.90", - "port": 80 - }, - { - "ip": "3.210.231.90", - "port": 8080 - }, - { - "ip": "3.210.231.90", - "port": 8443 - }, - { - "ip": "20.229.202.12", - "port": 8182 - }, - { - "ip": "20.229.202.12", - "port": 50443 - }, - { - "ip": "20.229.202.12", - "port": 50543 - }, - { - "ip": "49.12.6.38", - "port": 80 - }, - { - "ip": "49.12.6.38", - "port": 443 - }, - { - "ip": "49.12.6.38", - "port": 8880 - }, - { - "ip": "49.12.6.38", - "port": 12320 - }, - { - "ip": "49.12.6.38", - "port": 12321 - }, - { - "ip": "49.12.6.38", - "port": 12322 - }, - { - "ip": "54.87.101.217", - "port": 443 - }, - { - "ip": "54.87.101.217", - "port": 5985 - }, - { - "ip": "54.87.101.217", - "port": 8080 - }, - { - "ip": "54.87.101.217", - "port": 47001 - }, - { - "ip": "73.69.254.53", - "port": 80 - }, - { - "ip": "73.69.254.53", - "port": 443 - }, - { - "ip": "73.69.254.53", - "port": 8443 - }, - { - "ip": "3.248.60.69", - "port": 15443 - }, - { - "ip": "67.205.165.229", - "port": 80 - }, - { - "ip": "67.205.165.229", - "port": 443 - }, - { - "ip": "67.205.165.229", - "port": 3000 - }, - { - "ip": "67.205.165.229", - "port": 3001 - }, - { - "ip": "67.205.165.229", - "port": 8080 - }, - { - "ip": "35.172.60.205", - "port": 80 - }, - { - "ip": "35.172.60.205", - "port": 443 - }, - { - "ip": "35.162.13.216", - "port": 80 - }, - { - "ip": "35.162.13.216", - "port": 443 - }, - { - "ip": "3.39.49.4", - "port": 80 - }, - { - "ip": "3.39.49.4", - "port": 443 - }, - { - "ip": "15.165.123.84", - "port": 80 - }, - { - "ip": "15.165.123.84", - "port": 443 - }, - { - "ip": "20.65.43.96", - "port": 443 - }, - { - "ip": "143.198.175.164", - "port": 80 - }, - { - "ip": "143.198.175.164", - "port": 443 - }, - { - "ip": "35.82.73.66", - "port": 80 - }, - { - "ip": "35.82.73.66", - "port": 443 - }, - { - "ip": "54.66.19.74", - "port": 80 - }, - { - "ip": "54.66.19.74", - "port": 443 - }, - { - "ip": "188.120.255.3", - "port": 80 - }, - { - "ip": "188.120.255.3", - "port": 443 - }, - { - "ip": "202.182.98.255", - "port": 80 - }, - { - "ip": "202.182.98.255", - "port": 443 - }, - { - "ip": "49.125.130.72", - "port": 8080 - }, - { - "ip": "49.125.130.72", - "port": 8081 - }, - { - "ip": "49.125.130.72", - "port": 8082 - }, - { - "ip": "49.125.130.72", - "port": 8888 - }, - { - "ip": "49.125.130.72", - "port": 9090 - }, - { - "ip": "192.82.22.69", - "port": 80 - }, - { - "ip": "192.82.22.69", - "port": 443 - }, - { - "ip": "149.28.162.101", - "port": 80 - }, - { - "ip": "149.28.162.101", - "port": 443 - }, - { - "ip": "149.28.162.101", - "port": 8080 - }, - { - "ip": "185.209.163.1", - "port": 5000 - }, - { - "ip": "185.209.163.1", - "port": 7000 - }, - { - "ip": "185.209.163.1", - "port": 7200 - }, - { - "ip": "185.209.163.1", - "port": 8080 - }, - { - "ip": "185.209.163.1", - "port": 8083 - }, - { - "ip": "185.209.163.1", - "port": 9100 - }, - { - "ip": "185.209.163.1", - "port": 25080 - }, - { - "ip": "54.187.116.201", - "port": 443 - }, - { - "ip": "139.162.27.20", - "port": 3000 - }, - { - "ip": "139.162.27.20", - "port": 8080 - }, - { - "ip": "139.162.27.20", - "port": 8443 - }, - { - "ip": "54.187.11.200", - "port": 80 - }, - { - "ip": "54.187.11.200", - "port": 443 - }, - { - "ip": "138.201.230.122", - "port": 443 - }, - { - "ip": "138.201.230.122", - "port": 8080 - }, - { - "ip": "3.210.222.175", - "port": 3080 - }, - { - "ip": "3.210.222.175", - "port": 3443 - }, - { - "ip": "3.210.222.175", - "port": 5000 - }, - { - "ip": "3.210.222.175", - "port": 9191 - }, - { - "ip": "64.113.113.177", - "port": 80 - }, - { - "ip": "64.113.113.177", - "port": 443 - }, - { - "ip": "64.113.113.177", - "port": 2022 - }, - { - "ip": "167.114.3.115", - "port": 1337 - }, - { - "ip": "167.114.3.115", - "port": 8080 - }, - { - "ip": "167.114.3.115", - "port": 9001 - }, - { - "ip": "167.114.3.115", - "port": 9091 - }, - { - "ip": "34.217.113.248", - "port": 443 - }, - { - "ip": "18.142.13.51", - "port": 80 - }, - { - "ip": "18.142.13.51", - "port": 443 - }, - { - "ip": "18.142.13.51", - "port": 3000 - }, - { - "ip": "18.142.13.51", - "port": 8200 - }, - { - "ip": "52.3.182.86", - "port": 80 - }, - { - "ip": "52.3.182.86", - "port": 443 - }, - { - "ip": "52.3.182.86", - "port": 8443 - }, - { - "ip": "54.173.238.250", - "port": 80 - }, - { - "ip": "54.173.238.250", - "port": 443 - }, - { - "ip": "54.173.238.250", - "port": 8080 - }, - { - "ip": "207.38.89.104", - "port": 80 - }, - { - "ip": "207.38.89.104", - "port": 443 - }, - { - "ip": "207.38.89.104", - "port": 3010 - }, - { - "ip": "207.38.89.104", - "port": 8080 - }, - { - "ip": "207.38.89.104", - "port": 8086 - }, - { - "ip": "207.38.89.104", - "port": 9084 - }, - { - "ip": "207.38.89.104", - "port": 9085 - }, - { - "ip": "207.38.89.104", - "port": 9086 - }, - { - "ip": "207.38.89.104", - "port": 9087 - }, - { - "ip": "207.38.89.104", - "port": 9088 - }, - { - "ip": "207.38.89.104", - "port": 9089 - }, - { - "ip": "207.38.89.104", - "port": 9090 - }, - { - "ip": "207.38.89.104", - "port": 9091 - }, - { - "ip": "207.38.89.104", - "port": 9092 - }, - { - "ip": "207.38.89.104", - "port": 9093 - }, - { - "ip": "207.38.89.104", - "port": 9094 - }, - { - "ip": "20.18.39.93", - "port": 8080 - }, - { - "ip": "35.244.147.98", - "port": 80 - }, - { - "ip": "35.244.147.98", - "port": 443 - }, - { - "ip": "198.74.56.172", - "port": 80 - }, - { - "ip": "198.74.56.172", - "port": 443 - }, - { - "ip": "198.74.56.172", - "port": 2082 - }, - { - "ip": "198.74.56.172", - "port": 2083 - }, - { - "ip": "198.74.56.172", - "port": 2086 - }, - { - "ip": "198.74.56.172", - "port": 2087 - }, - { - "ip": "198.74.56.172", - "port": 2095 - }, - { - "ip": "198.74.56.172", - "port": 2096 - }, - { - "ip": "198.74.56.172", - "port": 8080 - }, - { - "ip": "198.74.56.172", - "port": 8081 - }, - { - "ip": "35.164.4.88", - "port": 80 - }, - { - "ip": "35.164.4.88", - "port": 443 - }, - { - "ip": "193.31.117.89", - "port": 80 - }, - { - "ip": "193.31.117.89", - "port": 443 - }, - { - "ip": "193.31.117.89", - "port": 8182 - }, - { - "ip": "193.31.117.89", - "port": 8987 - }, - { - "ip": "195.26.63.46", - "port": 80 - }, - { - "ip": "195.26.63.46", - "port": 443 - }, - { - "ip": "195.26.63.46", - "port": 8070 - }, - { - "ip": "195.26.63.46", - "port": 8809 - }, - { - "ip": "195.26.63.46", - "port": 8845 - }, - { - "ip": "195.26.63.46", - "port": 20001 - }, - { - "ip": "54.160.9.172", - "port": 80 - }, - { - "ip": "54.160.9.172", - "port": 443 - }, - { - "ip": "54.160.9.172", - "port": 8080 - }, - { - "ip": "34.91.103.74", - "port": 80 - }, - { - "ip": "34.91.103.74", - "port": 443 - }, - { - "ip": "34.91.103.74", - "port": 6001 - }, - { - "ip": "34.91.103.74", - "port": 8000 - }, - { - "ip": "34.91.103.74", - "port": 8080 - }, - { - "ip": "35.155.14.38", - "port": 80 - }, - { - "ip": "35.155.14.38", - "port": 443 - }, - { - "ip": "13.234.233.102", - "port": 80 - }, - { - "ip": "13.234.233.102", - "port": 443 - }, - { - "ip": "13.234.233.102", - "port": 5000 - }, - { - "ip": "13.234.233.102", - "port": 8080 - }, - { - "ip": "46.101.63.15", - "port": 80 - }, - { - "ip": "46.101.63.15", - "port": 443 - }, - { - "ip": "46.101.63.15", - "port": 8080 - }, - { - "ip": "54.90.81.200", - "port": 80 - }, - { - "ip": "54.90.81.200", - "port": 443 - }, - { - "ip": "3.211.61.153", - "port": 80 - }, - { - "ip": "3.211.61.153", - "port": 443 - }, - { - "ip": "142.132.217.44", - "port": 80 - }, - { - "ip": "142.132.217.44", - "port": 443 - }, - { - "ip": "142.132.217.44", - "port": 1000 - }, - { - "ip": "142.132.217.44", - "port": 5357 - }, - { - "ip": "142.132.217.44", - "port": 5985 - }, - { - "ip": "142.132.217.44", - "port": 8081 - }, - { - "ip": "142.132.217.44", - "port": 8443 - }, - { - "ip": "4.234.93.156", - "port": 80 - }, - { - "ip": "4.234.93.156", - "port": 443 - }, - { - "ip": "4.234.93.156", - "port": 3000 - }, - { - "ip": "4.234.93.156", - "port": 8080 - }, - { - "ip": "147.182.249.210", - "port": 80 - }, - { - "ip": "147.182.249.210", - "port": 443 - }, - { - "ip": "147.182.249.210", - "port": 9977 - }, - { - "ip": "62.84.116.145", - "port": 443 - }, - { - "ip": "178.63.95.86", - "port": 80 - }, - { - "ip": "178.63.95.86", - "port": 443 - }, - { - "ip": "178.63.95.86", - "port": 2096 - }, - { - "ip": "178.63.95.86", - "port": 3001 - }, - { - "ip": "178.63.95.86", - "port": 3003 - }, - { - "ip": "178.63.95.86", - "port": 4001 - }, - { - "ip": "178.63.95.86", - "port": 7000 - }, - { - "ip": "178.63.95.86", - "port": 7001 - }, - { - "ip": "178.63.95.86", - "port": 7002 - }, - { - "ip": "178.63.95.86", - "port": 8080 - }, - { - "ip": "178.63.95.86", - "port": 8088 - }, - { - "ip": "178.63.95.86", - "port": 8443 - }, - { - "ip": "210.54.38.65", - "port": 8082 - }, - { - "ip": "52.33.38.133", - "port": 80 - }, - { - "ip": "52.33.38.133", - "port": 443 - }, - { - "ip": "54.189.21.236", - "port": 80 - }, - { - "ip": "54.189.21.236", - "port": 443 - }, - { - "ip": "34.223.135.203", - "port": 80 - }, - { - "ip": "34.223.135.203", - "port": 443 - }, - { - "ip": "49.12.196.196", - "port": 443 - }, - { - "ip": "49.12.196.196", - "port": 5050 - }, - { - "ip": "49.12.196.196", - "port": 19999 - }, - { - "ip": "52.209.148.120", - "port": 80 - }, - { - "ip": "52.209.148.120", - "port": 443 - }, - { - "ip": "52.209.148.120", - "port": 2222 - }, - { - "ip": "52.209.148.120", - "port": 3001 - }, - { - "ip": "52.209.148.120", - "port": 3002 - }, - { - "ip": "52.209.148.120", - "port": 3009 - }, - { - "ip": "52.209.148.120", - "port": 3283 - }, - { - "ip": "52.209.148.120", - "port": 3456 - }, - { - "ip": "52.209.148.120", - "port": 6969 - }, - { - "ip": "52.209.148.120", - "port": 8085 - }, - { - "ip": "52.209.148.120", - "port": 8089 - }, - { - "ip": "52.209.148.120", - "port": 8623 - }, - { - "ip": "198.199.82.188", - "port": 443 - }, - { - "ip": "139.177.183.54", - "port": 80 - }, - { - "ip": "139.177.183.54", - "port": 443 - }, - { - "ip": "139.177.183.54", - "port": 6001 - }, - { - "ip": "139.177.183.54", - "port": 8008 - }, - { - "ip": "139.177.183.54", - "port": 44300 - }, - { - "ip": "52.8.204.63", - "port": 80 - }, - { - "ip": "52.8.204.63", - "port": 443 - }, - { - "ip": "18.166.253.240", - "port": 80 - }, - { - "ip": "18.166.253.240", - "port": 443 - }, - { - "ip": "52.63.24.193", - "port": 80 - }, - { - "ip": "52.63.24.193", - "port": 443 - }, - { - "ip": "161.35.55.229", - "port": 80 - }, - { - "ip": "161.35.55.229", - "port": 443 - }, - { - "ip": "161.35.55.229", - "port": 4856 - }, - { - "ip": "167.99.13.115", - "port": 80 - }, - { - "ip": "167.99.13.115", - "port": 443 - }, - { - "ip": "167.99.13.115", - "port": 9000 - }, - { - "ip": "3.135.179.5", - "port": 80 - }, - { - "ip": "3.135.179.5", - "port": 443 - }, - { - "ip": "3.135.179.5", - "port": 5000 - }, - { - "ip": "3.135.179.5", - "port": 5001 - }, - { - "ip": "3.135.179.5", - "port": 8080 - }, - { - "ip": "3.135.179.5", - "port": 9876 - }, - { - "ip": "54.194.128.210", - "port": 443 - }, - { - "ip": "54.194.128.210", - "port": 8443 - }, - { - "ip": "54.194.128.210", - "port": 8444 - }, - { - "ip": "165.227.175.80", - "port": 443 - }, - { - "ip": "52.27.84.52", - "port": 443 - }, - { - "ip": "52.28.13.14", - "port": 80 - }, - { - "ip": "52.28.13.14", - "port": 443 - }, - { - "ip": "31.156.51.172", - "port": 80 - }, - { - "ip": "31.156.51.172", - "port": 443 - }, - { - "ip": "31.156.51.172", - "port": 1234 - }, - { - "ip": "42.98.63.58", - "port": 443 - }, - { - "ip": "42.98.63.58", - "port": 5000 - }, - { - "ip": "42.98.63.58", - "port": 5001 - }, - { - "ip": "42.98.63.58", - "port": 8080 - }, - { - "ip": "42.98.63.58", - "port": 8081 - }, - { - "ip": "42.98.63.58", - "port": 8443 - }, - { - "ip": "42.98.63.58", - "port": 9008 - }, - { - "ip": "51.116.234.145", - "port": 443 - }, - { - "ip": "54.174.219.37", - "port": 443 - }, - { - "ip": "15.236.93.182", - "port": 80 - }, - { - "ip": "15.236.93.182", - "port": 443 - }, - { - "ip": "35.157.168.10", - "port": 443 - }, - { - "ip": "54.167.35.223", - "port": 443 - }, - { - "ip": "84.38.186.123", - "port": 80 - }, - { - "ip": "84.38.186.123", - "port": 443 - }, - { - "ip": "84.38.186.123", - "port": 5060 - }, - { - "ip": "84.38.186.123", - "port": 5061 - }, - { - "ip": "84.38.186.123", - "port": 8080 - }, - { - "ip": "84.38.186.123", - "port": 8081 - }, - { - "ip": "84.38.186.123", - "port": 8082 - }, - { - "ip": "84.38.186.123", - "port": 8083 - }, - { - "ip": "84.38.186.123", - "port": 8084 - }, - { - "ip": "84.38.186.123", - "port": 8085 - }, - { - "ip": "84.38.186.123", - "port": 8086 - }, - { - "ip": "84.38.186.123", - "port": 8087 - }, - { - "ip": "84.38.186.123", - "port": 8088 - }, - { - "ip": "84.38.186.123", - "port": 8090 - }, - { - "ip": "84.38.186.123", - "port": 8443 - }, - { - "ip": "52.22.203.96", - "port": 80 - }, - { - "ip": "52.22.203.96", - "port": 443 - }, - { - "ip": "99.81.70.47", - "port": 80 - }, - { - "ip": "99.81.70.47", - "port": 443 - }, - { - "ip": "4.204.237.107", - "port": 80 - }, - { - "ip": "4.204.237.107", - "port": 443 - }, - { - "ip": "18.176.230.57", - "port": 80 - }, - { - "ip": "18.176.230.57", - "port": 443 - }, - { - "ip": "44.215.26.133", - "port": 80 - }, - { - "ip": "44.215.26.133", - "port": 443 - }, - { - "ip": "44.215.26.133", - "port": 8080 - }, - { - "ip": "44.215.26.133", - "port": 11443 - }, - { - "ip": "47.93.250.142", - "port": 80 - }, - { - "ip": "47.93.250.142", - "port": 443 - }, - { - "ip": "47.93.250.142", - "port": 2333 - }, - { - "ip": "52.31.24.250", - "port": 80 - }, - { - "ip": "52.31.24.250", - "port": 443 - }, - { - "ip": "85.241.172.24", - "port": 8280 - }, - { - "ip": "85.241.172.24", - "port": 8883 - }, - { - "ip": "3.83.46.138", - "port": 80 - }, - { - "ip": "3.83.46.138", - "port": 443 - }, - { - "ip": "3.83.46.138", - "port": 4000 - }, - { - "ip": "4.227.144.179", - "port": 80 - }, - { - "ip": "4.227.144.179", - "port": 443 - }, - { - "ip": "51.158.153.126", - "port": 5900 - }, - { - "ip": "51.158.153.126", - "port": 8080 - }, - { - "ip": "51.158.153.126", - "port": 8087 - }, - { - "ip": "141.94.244.213", - "port": 443 - }, - { - "ip": "3.98.141.104", - "port": 80 - }, - { - "ip": "3.98.141.104", - "port": 81 - }, - { - "ip": "3.98.141.104", - "port": 443 - }, - { - "ip": "3.98.141.104", - "port": 8080 - }, - { - "ip": "3.98.141.104", - "port": 9008 - }, - { - "ip": "87.106.253.191", - "port": 80 - }, - { - "ip": "87.106.253.191", - "port": 443 - }, - { - "ip": "87.106.253.191", - "port": 1080 - }, - { - "ip": "87.106.253.191", - "port": 2080 - }, - { - "ip": "87.106.253.191", - "port": 3118 - }, - { - "ip": "87.106.253.191", - "port": 5181 - }, - { - "ip": "87.106.253.191", - "port": 6080 - }, - { - "ip": "87.106.253.191", - "port": 7443 - }, - { - "ip": "87.106.253.191", - "port": 9090 - }, - { - "ip": "87.106.253.191", - "port": 9191 - }, - { - "ip": "182.92.7.27", - "port": 80 - }, - { - "ip": "182.92.7.27", - "port": 443 - }, - { - "ip": "182.92.7.27", - "port": 3000 - }, - { - "ip": "182.92.7.27", - "port": 4000 - }, - { - "ip": "182.92.7.27", - "port": 4443 - }, - { - "ip": "182.92.7.27", - "port": 8080 - }, - { - "ip": "182.92.7.27", - "port": 8888 - }, - { - "ip": "182.92.7.27", - "port": 8989 - }, - { - "ip": "182.92.7.27", - "port": 9090 - }, - { - "ip": "34.218.183.145", - "port": 443 - }, - { - "ip": "45.56.127.164", - "port": 80 - }, - { - "ip": "45.56.127.164", - "port": 3000 - }, - { - "ip": "45.56.127.164", - "port": 3002 - }, - { - "ip": "45.56.127.164", - "port": 3005 - }, - { - "ip": "45.56.127.164", - "port": 8080 - }, - { - "ip": "35.172.68.252", - "port": 80 - }, - { - "ip": "35.172.68.252", - "port": 443 - }, - { - "ip": "23.23.101.198", - "port": 80 - }, - { - "ip": "23.23.101.198", - "port": 443 - }, - { - "ip": "20.51.249.171", - "port": 80 - }, - { - "ip": "20.51.249.171", - "port": 443 - }, - { - "ip": "20.51.249.171", - "port": 3000 - }, - { - "ip": "20.51.249.171", - "port": 4000 - }, - { - "ip": "20.51.249.171", - "port": 4444 - }, - { - "ip": "20.51.249.171", - "port": 5000 - }, - { - "ip": "20.51.249.171", - "port": 5050 - }, - { - "ip": "20.51.249.171", - "port": 5100 - }, - { - "ip": "20.51.249.171", - "port": 5500 - }, - { - "ip": "20.51.249.171", - "port": 5984 - }, - { - "ip": "20.51.249.171", - "port": 7984 - }, - { - "ip": "20.51.249.171", - "port": 8000 - }, - { - "ip": "20.51.249.171", - "port": 8082 - }, - { - "ip": "20.51.249.171", - "port": 9000 - }, - { - "ip": "20.51.249.171", - "port": 9054 - }, - { - "ip": "35.172.54.193", - "port": 80 - }, - { - "ip": "35.172.54.193", - "port": 443 - }, - { - "ip": "5.189.158.151", - "port": 80 - }, - { - "ip": "5.189.158.151", - "port": 443 - }, - { - "ip": "5.189.158.151", - "port": 8080 - }, - { - "ip": "5.189.158.151", - "port": 9606 - }, - { - "ip": "34.209.113.65", - "port": 443 - }, - { - "ip": "45.79.193.237", - "port": 80 - }, - { - "ip": "45.79.193.237", - "port": 443 - }, - { - "ip": "45.79.193.237", - "port": 5000 - }, - { - "ip": "45.79.193.237", - "port": 5555 - }, - { - "ip": "45.79.193.237", - "port": 8088 - }, - { - "ip": "52.2.184.244", - "port": 80 - }, - { - "ip": "52.2.184.244", - "port": 443 - }, - { - "ip": "13.232.174.178", - "port": 443 - }, - { - "ip": "2A02:C207:2056:5545:0000:0000:0000:0001", - "port": 80 - }, - { - "ip": "2A02:C207:2056:5545:0000:0000:0000:0001", - "port": 443 - }, - { - "ip": "163.172.63.156", - "port": 4444 - }, - { - "ip": "163.172.63.156", - "port": 8384 - }, - { - "ip": "195.201.95.14", - "port": 3002 - }, - { - "ip": "34.213.254.44", - "port": 80 - }, - { - "ip": "34.213.254.44", - "port": 443 - }, - { - "ip": "40.127.12.114", - "port": 443 - }, - { - "ip": "40.127.12.114", - "port": 5443 - }, - { - "ip": "40.127.12.114", - "port": 9443 - }, - { - "ip": "79.8.4.41", - "port": 80 - }, - { - "ip": "79.8.4.41", - "port": 96 - }, - { - "ip": "79.8.4.41", - "port": 443 - }, - { - "ip": "79.8.4.41", - "port": 8089 - }, - { - "ip": "79.8.4.41", - "port": 42944 - }, - { - "ip": "54.74.52.40", - "port": 80 - }, - { - "ip": "54.74.52.40", - "port": 443 - }, - { - "ip": "107.20.66.37", - "port": 80 - }, - { - "ip": "107.20.66.37", - "port": 443 - }, - { - "ip": "147.182.152.23", - "port": 80 - }, - { - "ip": "147.182.152.23", - "port": 443 - }, - { - "ip": "147.182.152.23", - "port": 3000 - }, - { - "ip": "147.182.152.23", - "port": 3128 - }, - { - "ip": "147.182.152.23", - "port": 8000 - }, - { - "ip": "147.182.152.23", - "port": 8081 - }, - { - "ip": "176.124.221.11", - "port": 443 - }, - { - "ip": "2001:19F0:5C01:1ABB:5400:02FF:FE74:5E3C", - "port": 443 - }, - { - "ip": "34.160.188.210", - "port": 80 - }, - { - "ip": "34.160.188.210", - "port": 443 - }, - { - "ip": "54.144.19.134", - "port": 80 - }, - { - "ip": "54.144.19.134", - "port": 443 - }, - { - "ip": "216.48.186.2", - "port": 80 - }, - { - "ip": "216.48.186.2", - "port": 443 - }, - { - "ip": "162.243.32.33", - "port": 80 - }, - { - "ip": "162.243.32.33", - "port": 443 - }, - { - "ip": "162.243.32.33", - "port": 5005 - }, - { - "ip": "162.243.32.33", - "port": 5010 - }, - { - "ip": "162.243.32.33", - "port": 5500 - }, - { - "ip": "162.243.32.33", - "port": 8080 - }, - { - "ip": "162.243.32.33", - "port": 8081 - }, - { - "ip": "162.243.32.33", - "port": 8084 - }, - { - "ip": "62.171.140.36", - "port": 80 - }, - { - "ip": "62.171.140.36", - "port": 443 - }, - { - "ip": "62.171.140.36", - "port": 8000 - }, - { - "ip": "62.171.140.36", - "port": 8080 - }, - { - "ip": "62.171.140.36", - "port": 8997 - }, - { - "ip": "62.171.140.36", - "port": 10000 - }, - { - "ip": "62.171.140.36", - "port": 19999 - }, - { - "ip": "62.171.140.36", - "port": 20000 - }, - { - "ip": "34.69.33.75", - "port": 80 - }, - { - "ip": "34.69.33.75", - "port": 443 - }, - { - "ip": "136.244.108.97", - "port": 443 - }, - { - "ip": "35.197.143.81", - "port": 80 - }, - { - "ip": "35.197.143.81", - "port": 443 - }, - { - "ip": "35.197.143.81", - "port": 6001 - }, - { - "ip": "35.197.143.81", - "port": 8000 - }, - { - "ip": "35.197.143.81", - "port": 8080 - }, - { - "ip": "152.67.44.31", - "port": 80 - }, - { - "ip": "152.67.44.31", - "port": 443 - }, - { - "ip": "152.67.44.31", - "port": 8045 - }, - { - "ip": "13.41.49.39", - "port": 80 - }, - { - "ip": "13.41.49.39", - "port": 443 - }, - { - "ip": "13.41.49.39", - "port": 3001 - }, - { - "ip": "13.41.49.39", - "port": 8080 - }, - { - "ip": "52.33.136.29", - "port": 443 - }, - { - "ip": "138.197.126.125", - "port": 80 - }, - { - "ip": "138.197.126.125", - "port": 443 - }, - { - "ip": "146.148.23.178", - "port": 6443 - }, - { - "ip": "146.148.23.178", - "port": 9000 - }, - { - "ip": "146.148.23.178", - "port": 9001 - }, - { - "ip": "167.71.166.217", - "port": 443 - }, - { - "ip": "3.212.228.65", - "port": 80 - }, - { - "ip": "3.212.228.65", - "port": 443 - }, - { - "ip": "157.90.162.204", - "port": 80 - }, - { - "ip": "157.90.162.204", - "port": 443 - }, - { - "ip": "3.140.212.26", - "port": 80 - }, - { - "ip": "3.140.212.26", - "port": 443 - }, - { - "ip": "140.238.221.133", - "port": 443 - }, - { - "ip": "188.165.253.106", - "port": 80 - }, - { - "ip": "188.165.253.106", - "port": 443 - }, - { - "ip": "34.196.151.245", - "port": 80 - }, - { - "ip": "34.196.151.245", - "port": 443 - }, - { - "ip": "34.196.151.245", - "port": 3000 - }, - { - "ip": "34.196.151.245", - "port": 8080 - }, - { - "ip": "44.226.172.204", - "port": 80 - }, - { - "ip": "44.226.172.204", - "port": 443 - }, - { - "ip": "44.226.172.204", - "port": 2425 - }, - { - "ip": "44.226.172.204", - "port": 2525 - }, - { - "ip": "44.226.172.204", - "port": 6060 - }, - { - "ip": "122.9.4.113", - "port": 80 - }, - { - "ip": "122.9.4.113", - "port": 443 - }, - { - "ip": "122.9.4.113", - "port": 888 - }, - { - "ip": "122.9.4.113", - "port": 3029 - }, - { - "ip": "122.9.4.113", - "port": 3030 - }, - { - "ip": "122.9.4.113", - "port": 8642 - }, - { - "ip": "122.9.4.113", - "port": 8888 - }, - { - "ip": "162.243.171.168", - "port": 69 - }, - { - "ip": "162.243.171.168", - "port": 80 - }, - { - "ip": "162.243.171.168", - "port": 443 - }, - { - "ip": "162.243.171.168", - "port": 3000 - }, - { - "ip": "162.243.171.168", - "port": 8080 - }, - { - "ip": "162.243.171.168", - "port": 8181 - }, - { - "ip": "20.203.175.62", - "port": 80 - }, - { - "ip": "20.203.175.62", - "port": 443 - }, - { - "ip": "20.203.175.62", - "port": 8080 - }, - { - "ip": "52.87.109.158", - "port": 80 - }, - { - "ip": "52.87.109.158", - "port": 443 - }, - { - "ip": "85.143.216.246", - "port": 443 - }, - { - "ip": "195.26.63.44", - "port": 80 - }, - { - "ip": "195.26.63.44", - "port": 8809 - }, - { - "ip": "195.26.63.44", - "port": 8810 - }, - { - "ip": "195.26.63.44", - "port": 8811 - }, - { - "ip": "195.26.63.44", - "port": 8845 - }, - { - "ip": "213.189.221.205", - "port": 80 - }, - { - "ip": "213.189.221.205", - "port": 443 - }, - { - "ip": "213.189.221.205", - "port": 3000 - }, - { - "ip": "213.189.221.205", - "port": 3100 - }, - { - "ip": "213.189.221.205", - "port": 8080 - }, - { - "ip": "34.208.131.93", - "port": 8080 - }, - { - "ip": "168.119.169.77", - "port": 80 - }, - { - "ip": "168.119.169.77", - "port": 443 - }, - { - "ip": "180.97.151.89", - "port": 80 - }, - { - "ip": "180.97.151.89", - "port": 443 - }, - { - "ip": "180.97.151.89", - "port": 5000 - }, - { - "ip": "180.97.151.89", - "port": 8080 - }, - { - "ip": "104.156.254.120", - "port": 80 - }, - { - "ip": "104.156.254.120", - "port": 443 - }, - { - "ip": "104.156.254.120", - "port": 7080 - }, - { - "ip": "104.156.254.120", - "port": 8080 - }, - { - "ip": "104.156.254.120", - "port": 8090 - }, - { - "ip": "3.21.116.156", - "port": 80 - }, - { - "ip": "3.21.116.156", - "port": 443 - }, - { - "ip": "3.21.116.156", - "port": 3000 - }, - { - "ip": "3.21.116.156", - "port": 5985 - }, - { - "ip": "3.21.116.156", - "port": 8081 - }, - { - "ip": "3.21.116.156", - "port": 47001 - }, - { - "ip": "54.149.179.16", - "port": 443 - }, - { - "ip": "143.178.34.238", - "port": 80 - }, - { - "ip": "143.178.34.238", - "port": 443 - }, - { - "ip": "143.178.34.238", - "port": 8000 - }, - { - "ip": "143.178.34.238", - "port": 8003 - }, - { - "ip": "143.178.34.238", - "port": 8009 - }, - { - "ip": "143.178.34.238", - "port": 8080 - }, - { - "ip": "143.178.34.238", - "port": 8443 - }, - { - "ip": "44.193.101.34", - "port": 80 - }, - { - "ip": "44.193.101.34", - "port": 443 - }, - { - "ip": "44.226.76.252", - "port": 443 - }, - { - "ip": "52.86.137.242", - "port": 443 - }, - { - "ip": "44.238.69.87", - "port": 80 - }, - { - "ip": "44.238.69.87", - "port": 443 - }, - { - "ip": "51.68.190.167", - "port": 443 - }, - { - "ip": "201.147.98.74", - "port": 80 - }, - { - "ip": "201.147.98.74", - "port": 443 - }, - { - "ip": "201.147.98.74", - "port": 4001 - }, - { - "ip": "201.147.98.74", - "port": 5001 - }, - { - "ip": "201.147.98.74", - "port": 6001 - }, - { - "ip": "201.147.98.74", - "port": 6003 - }, - { - "ip": "201.147.98.74", - "port": 6007 - }, - { - "ip": "201.147.98.74", - "port": 9001 - }, - { - "ip": "2001:41D0:0002:C86A:0000:0000:0000:0001", - "port": 80 - }, - { - "ip": "2001:41D0:0002:C86A:0000:0000:0000:0001", - "port": 443 - }, - { - "ip": "88.202.190.10", - "port": 80 - }, - { - "ip": "88.202.190.10", - "port": 443 - }, - { - "ip": "88.202.190.10", - "port": 3000 - }, - { - "ip": "88.202.190.10", - "port": 8080 - }, - { - "ip": "212.227.214.56", - "port": 443 - }, - { - "ip": "52.200.250.221", - "port": 80 - }, - { - "ip": "52.200.250.221", - "port": 443 - }, - { - "ip": "45.76.182.170", - "port": 80 - }, - { - "ip": "45.76.182.170", - "port": 443 - }, - { - "ip": "45.76.182.170", - "port": 8088 - }, - { - "ip": "54.79.134.242", - "port": 80 - }, - { - "ip": "54.79.134.242", - "port": 443 - }, - { - "ip": "78.28.252.101", - "port": 80 - }, - { - "ip": "78.28.252.101", - "port": 443 - }, - { - "ip": "78.28.252.101", - "port": 3002 - }, - { - "ip": "78.28.252.101", - "port": 3003 - }, - { - "ip": "78.28.252.101", - "port": 9999 - }, - { - "ip": "3.9.21.215", - "port": 80 - }, - { - "ip": "3.9.21.215", - "port": 443 - }, - { - "ip": "3.232.52.250", - "port": 80 - }, - { - "ip": "3.232.52.250", - "port": 443 - }, - { - "ip": "34.73.220.238", - "port": 80 - }, - { - "ip": "34.73.220.238", - "port": 443 - }, - { - "ip": "34.73.220.238", - "port": 3000 - }, - { - "ip": "34.73.220.238", - "port": 4010 - }, - { - "ip": "34.73.220.238", - "port": 8181 - }, - { - "ip": "34.78.71.65", - "port": 80 - }, - { - "ip": "34.78.71.65", - "port": 443 - }, - { - "ip": "194.67.106.229", - "port": 80 - }, - { - "ip": "194.67.106.229", - "port": 443 - }, - { - "ip": "194.67.106.229", - "port": 4000 - }, - { - "ip": "194.67.106.229", - "port": 5000 - }, - { - "ip": "194.67.106.229", - "port": 8080 - }, - { - "ip": "194.67.106.229", - "port": 8083 - }, - { - "ip": "101.33.122.244", - "port": 80 - }, - { - "ip": "101.33.122.244", - "port": 443 - }, - { - "ip": "101.33.122.244", - "port": 888 - }, - { - "ip": "101.33.122.244", - "port": 5000 - }, - { - "ip": "101.33.122.244", - "port": 8443 - }, - { - "ip": "101.33.122.244", - "port": 9001 - }, - { - "ip": "101.33.122.244", - "port": 9080 - }, - { - "ip": "101.33.122.244", - "port": 12345 - }, - { - "ip": "101.33.122.244", - "port": 23333 - }, - { - "ip": "141.94.68.55", - "port": 80 - }, - { - "ip": "141.94.68.55", - "port": 443 - }, - { - "ip": "141.94.68.55", - "port": 1210 - }, - { - "ip": "141.94.68.55", - "port": 1211 - }, - { - "ip": "141.94.68.55", - "port": 3000 - }, - { - "ip": "141.94.68.55", - "port": 8069 - }, - { - "ip": "141.94.68.55", - "port": 8072 - }, - { - "ip": "141.94.68.55", - "port": 9090 - }, - { - "ip": "141.94.68.55", - "port": 10000 - }, - { - "ip": "185.228.136.91", - "port": 80 - }, - { - "ip": "185.228.136.91", - "port": 443 - }, - { - "ip": "185.228.136.91", - "port": 5000 - }, - { - "ip": "185.228.136.91", - "port": 9433 - }, - { - "ip": "185.228.136.91", - "port": 11080 - }, - { - "ip": "185.228.136.91", - "port": 12080 - }, - { - "ip": "192.46.236.128", - "port": 443 - }, - { - "ip": "54.219.136.82", - "port": 80 - }, - { - "ip": "54.219.136.82", - "port": 443 - }, - { - "ip": "174.136.150.112", - "port": 80 - }, - { - "ip": "174.136.150.112", - "port": 443 - }, - { - "ip": "174.136.150.112", - "port": 2000 - }, - { - "ip": "34.224.158.102", - "port": 443 - }, - { - "ip": "130.162.40.87", - "port": 80 - }, - { - "ip": "130.162.40.87", - "port": 81 - }, - { - "ip": "130.162.40.87", - "port": 443 - }, - { - "ip": "130.162.40.87", - "port": 5678 - }, - { - "ip": "130.162.40.87", - "port": 8083 - }, - { - "ip": "43.200.12.116", - "port": 80 - }, - { - "ip": "43.200.12.116", - "port": 443 - }, - { - "ip": "80.85.142.238", - "port": 80 - }, - { - "ip": "80.85.142.238", - "port": 443 - }, - { - "ip": "80.85.142.238", - "port": 8080 - }, - { - "ip": "80.85.142.238", - "port": 8443 - }, - { - "ip": "35.199.183.29", - "port": 80 - }, - { - "ip": "35.199.183.29", - "port": 443 - }, - { - "ip": "52.69.32.228", - "port": 80 - }, - { - "ip": "52.69.32.228", - "port": 443 - }, - { - "ip": "188.166.119.245", - "port": 80 - }, - { - "ip": "188.166.119.245", - "port": 443 - }, - { - "ip": "188.166.119.245", - "port": 8080 - }, - { - "ip": "44.238.80.241", - "port": 80 - }, - { - "ip": "44.238.80.241", - "port": 443 - }, - { - "ip": "45.55.101.19", - "port": 80 - }, - { - "ip": "45.55.101.19", - "port": 443 - }, - { - "ip": "45.55.101.19", - "port": 5005 - }, - { - "ip": "45.55.101.19", - "port": 5010 - }, - { - "ip": "45.55.101.19", - "port": 5500 - }, - { - "ip": "45.55.101.19", - "port": 8080 - }, - { - "ip": "45.55.101.19", - "port": 8081 - }, - { - "ip": "45.55.101.19", - "port": 8084 - }, - { - "ip": "52.205.83.58", - "port": 80 - }, - { - "ip": "52.205.83.58", - "port": 443 - }, - { - "ip": "2600:3C00:0000:0000:F03C:93FF:FEDC:A1B2", - "port": 80 - }, - { - "ip": "2600:3C00:0000:0000:F03C:93FF:FEDC:A1B2", - "port": 443 - }, - { - "ip": "198.211.109.231", - "port": 80 - }, - { - "ip": "198.211.109.231", - "port": 443 - }, - { - "ip": "13.112.234.115", - "port": 48888 - }, - { - "ip": "34.198.10.7", - "port": 80 - }, - { - "ip": "34.198.10.7", - "port": 443 - }, - { - "ip": "34.234.241.233", - "port": 80 - }, - { - "ip": "34.234.241.233", - "port": 443 - }, - { - "ip": "54.158.207.83", - "port": 80 - }, - { - "ip": "54.158.207.83", - "port": 443 - }, - { - "ip": "149.28.148.8", - "port": 80 - }, - { - "ip": "149.28.148.8", - "port": 443 - }, - { - "ip": "149.28.148.8", - "port": 3333 - }, - { - "ip": "149.28.148.8", - "port": 8000 - }, - { - "ip": "149.28.148.8", - "port": 8001 - }, - { - "ip": "149.28.148.8", - "port": 8002 - }, - { - "ip": "149.28.148.8", - "port": 8006 - }, - { - "ip": "149.28.148.8", - "port": 8007 - }, - { - "ip": "149.28.148.8", - "port": 8009 - }, - { - "ip": "149.28.148.8", - "port": 8010 - }, - { - "ip": "149.28.148.8", - "port": 8011 - }, - { - "ip": "149.28.148.8", - "port": 8012 - }, - { - "ip": "149.28.148.8", - "port": 8013 - }, - { - "ip": "149.28.148.8", - "port": 8020 - }, - { - "ip": "149.28.148.8", - "port": 8888 - }, - { - "ip": "149.28.148.8", - "port": 19999 - }, - { - "ip": "50.206.39.8", - "port": 80 - }, - { - "ip": "50.206.39.8", - "port": 8080 - }, - { - "ip": "150.164.32.50", - "port": 80 - }, - { - "ip": "150.164.32.50", - "port": 443 - }, - { - "ip": "150.164.32.50", - "port": 8001 - }, - { - "ip": "150.164.32.50", - "port": 8002 - }, - { - "ip": "150.164.32.50", - "port": 8080 - }, - { - "ip": "150.164.32.50", - "port": 8082 - }, - { - "ip": "150.164.32.50", - "port": 22080 - }, - { - "ip": "150.164.32.50", - "port": 24080 - }, - { - "ip": "150.164.32.50", - "port": 25080 - }, - { - "ip": "150.164.32.50", - "port": 38080 - }, - { - "ip": "150.164.32.50", - "port": 48081 - }, - { - "ip": "150.164.32.50", - "port": 53554 - }, - { - "ip": "161.35.168.225", - "port": 9000 - }, - { - "ip": "18.188.102.140", - "port": 443 - }, - { - "ip": "18.188.102.140", - "port": 5000 - }, - { - "ip": "18.188.102.140", - "port": 5005 - }, - { - "ip": "18.188.102.140", - "port": 5050 - }, - { - "ip": "18.188.102.140", - "port": 6001 - }, - { - "ip": "18.188.102.140", - "port": 6002 - }, - { - "ip": "18.188.102.140", - "port": 6006 - }, - { - "ip": "18.188.102.140", - "port": 8080 - }, - { - "ip": "54.70.208.29", - "port": 80 - }, - { - "ip": "54.70.208.29", - "port": 443 - }, - { - "ip": "116.203.194.203", - "port": 80 - }, - { - "ip": "116.203.194.203", - "port": 443 - }, - { - "ip": "116.203.194.203", - "port": 2053 - }, - { - "ip": "116.203.194.203", - "port": 2095 - }, - { - "ip": "116.203.194.203", - "port": 2096 - }, - { - "ip": "116.203.194.203", - "port": 8000 - }, - { - "ip": "116.203.194.203", - "port": 8010 - }, - { - "ip": "116.203.194.203", - "port": 8050 - }, - { - "ip": "116.203.194.203", - "port": 8080 - }, - { - "ip": "116.203.194.203", - "port": 8200 - }, - { - "ip": "116.203.194.203", - "port": 8300 - }, - { - "ip": "116.203.194.203", - "port": 8443 - }, - { - "ip": "116.203.194.203", - "port": 8500 - }, - { - "ip": "116.203.194.203", - "port": 8600 - }, - { - "ip": "116.203.194.203", - "port": 8700 - }, - { - "ip": "3.132.208.112", - "port": 80 - }, - { - "ip": "3.132.208.112", - "port": 443 - }, - { - "ip": "3.132.208.112", - "port": 5985 - }, - { - "ip": "3.132.208.112", - "port": 8080 - }, - { - "ip": "34.117.151.248", - "port": 80 - }, - { - "ip": "34.117.151.248", - "port": 443 - }, - { - "ip": "34.117.151.248", - "port": 8085 - }, - { - "ip": "173.243.226.1", - "port": 443 - }, - { - "ip": "54.94.33.42", - "port": 443 - }, - { - "ip": "54.94.33.42", - "port": 4000 - }, - { - "ip": "54.94.33.42", - "port": 4001 - }, - { - "ip": "54.94.33.42", - "port": 6000 - }, - { - "ip": "54.94.33.42", - "port": 7000 - }, - { - "ip": "54.94.33.42", - "port": 7001 - }, - { - "ip": "54.94.33.42", - "port": 7002 - }, - { - "ip": "54.94.33.42", - "port": 7050 - }, - { - "ip": "54.94.33.42", - "port": 7500 - }, - { - "ip": "54.94.33.42", - "port": 8000 - }, - { - "ip": "54.94.33.42", - "port": 8002 - }, - { - "ip": "54.94.33.42", - "port": 8003 - }, - { - "ip": "54.94.33.42", - "port": 8010 - }, - { - "ip": "54.94.33.42", - "port": 8050 - }, - { - "ip": "54.94.33.42", - "port": 8700 - }, - { - "ip": "54.94.33.42", - "port": 8888 - }, - { - "ip": "54.94.33.42", - "port": 9001 - }, - { - "ip": "54.94.33.42", - "port": 9005 - }, - { - "ip": "54.94.33.42", - "port": 9006 - }, - { - "ip": "54.94.33.42", - "port": 9007 - }, - { - "ip": "54.94.33.42", - "port": 9008 - }, - { - "ip": "54.94.33.42", - "port": 9010 - }, - { - "ip": "54.94.33.42", - "port": 9011 - }, - { - "ip": "54.94.33.42", - "port": 9999 - }, - { - "ip": "54.94.33.42", - "port": 30000 - }, - { - "ip": "54.146.92.6", - "port": 80 - }, - { - "ip": "54.146.92.6", - "port": 443 - }, - { - "ip": "178.255.44.90", - "port": 80 - }, - { - "ip": "178.255.44.90", - "port": 443 - }, - { - "ip": "178.255.44.90", - "port": 2222 - }, - { - "ip": "178.255.44.90", - "port": 8080 - }, - { - "ip": "46.19.9.48", - "port": 80 - }, - { - "ip": "46.19.9.48", - "port": 443 - }, - { - "ip": "46.19.9.48", - "port": 8899 - }, - { - "ip": "185.48.122.62", - "port": 443 - }, - { - "ip": "18.179.137.237", - "port": 48888 - }, - { - "ip": "34.90.132.64", - "port": 80 - }, - { - "ip": "34.90.132.64", - "port": 443 - }, - { - "ip": "150.164.32.239", - "port": 80 - }, - { - "ip": "150.164.32.239", - "port": 443 - }, - { - "ip": "35.195.99.115", - "port": 6443 - }, - { - "ip": "45.33.69.163", - "port": 80 - }, - { - "ip": "45.33.69.163", - "port": 443 - }, - { - "ip": "45.33.69.163", - "port": 4001 - }, - { - "ip": "152.67.113.26", - "port": 80 - }, - { - "ip": "152.67.113.26", - "port": 443 - }, - { - "ip": "152.67.113.26", - "port": 888 - }, - { - "ip": "152.67.113.26", - "port": 1200 - }, - { - "ip": "152.67.113.26", - "port": 8888 - }, - { - "ip": "175.27.187.83", - "port": 80 - }, - { - "ip": "175.27.187.83", - "port": 443 - }, - { - "ip": "175.27.187.83", - "port": 4000 - }, - { - "ip": "44.240.14.117", - "port": 80 - }, - { - "ip": "44.240.14.117", - "port": 443 - }, - { - "ip": "13.80.79.84", - "port": 80 - }, - { - "ip": "13.80.79.84", - "port": 442 - }, - { - "ip": "13.80.79.84", - "port": 443 - }, - { - "ip": "13.80.79.84", - "port": 4455 - }, - { - "ip": "13.80.79.84", - "port": 8079 - }, - { - "ip": "13.80.79.84", - "port": 8080 - }, - { - "ip": "13.80.79.84", - "port": 8999 - }, - { - "ip": "34.216.55.139", - "port": 80 - }, - { - "ip": "34.216.55.139", - "port": 443 - }, - { - "ip": "40.121.80.121", - "port": 443 - }, - { - "ip": "3.85.116.117", - "port": 80 - }, - { - "ip": "3.85.116.117", - "port": 443 - }, - { - "ip": "5.161.34.252", - "port": 80 - }, - { - "ip": "5.161.34.252", - "port": 443 - }, - { - "ip": "52.79.255.170", - "port": 443 - }, - { - "ip": "172.104.202.185", - "port": 443 - }, - { - "ip": "18.198.148.109", - "port": 80 - }, - { - "ip": "18.198.148.109", - "port": 443 - }, - { - "ip": "46.231.206.125", - "port": 80 - }, - { - "ip": "46.231.206.125", - "port": 443 - }, - { - "ip": "46.231.206.125", - "port": 8080 - }, - { - "ip": "82.79.128.202", - "port": 8089 - }, - { - "ip": "82.79.128.202", - "port": 8090 - }, - { - "ip": "178.128.176.143", - "port": 80 - }, - { - "ip": "178.128.176.143", - "port": 443 - }, - { - "ip": "34.117.5.125", - "port": 80 - }, - { - "ip": "34.117.5.125", - "port": 443 - }, - { - "ip": "34.117.5.125", - "port": 8085 - }, - { - "ip": "85.215.105.216", - "port": 80 - }, - { - "ip": "85.215.105.216", - "port": 443 - }, - { - "ip": "85.215.105.216", - "port": 8888 - }, - { - "ip": "85.215.105.216", - "port": 9042 - }, - { - "ip": "116.203.4.214", - "port": 80 - }, - { - "ip": "116.203.4.214", - "port": 443 - }, - { - "ip": "116.203.245.53", - "port": 80 - }, - { - "ip": "116.203.245.53", - "port": 443 - }, - { - "ip": "116.203.245.53", - "port": 8080 - }, - { - "ip": "162.212.158.100", - "port": 80 - }, - { - "ip": "162.212.158.100", - "port": 443 - }, - { - "ip": "162.212.158.100", - "port": 3100 - }, - { - "ip": "162.212.158.100", - "port": 3128 - }, - { - "ip": "162.212.158.100", - "port": 8095 - }, - { - "ip": "162.212.158.100", - "port": 9325 - }, - { - "ip": "162.212.158.100", - "port": 9335 - }, - { - "ip": "165.22.140.58", - "port": 80 - }, - { - "ip": "165.22.140.58", - "port": 443 - }, - { - "ip": "165.22.140.58", - "port": 8443 - }, - { - "ip": "18.198.148.109", - "port": 80 - }, - { - "ip": "18.198.148.109", - "port": 443 - }, - { - "ip": "46.231.206.125", - "port": 80 - }, - { - "ip": "46.231.206.125", - "port": 443 - }, - { - "ip": "46.231.206.125", - "port": 8080 - }, - { - "ip": "82.79.128.202", - "port": 8089 - }, - { - "ip": "82.79.128.202", - "port": 8090 - }, - { - "ip": "178.128.176.143", - "port": 80 - }, - { - "ip": "178.128.176.143", - "port": 443 - }, - { - "ip": "132.145.54.162", - "port": 443 - }, - { - "ip": "18.230.183.15", - "port": 443 - }, - { - "ip": "18.230.183.15", - "port": 4000 - }, - { - "ip": "18.230.183.15", - "port": 4001 - }, - { - "ip": "18.230.183.15", - "port": 6000 - }, - { - "ip": "18.230.183.15", - "port": 6050 - }, - { - "ip": "18.230.183.15", - "port": 7000 - }, - { - "ip": "18.230.183.15", - "port": 7001 - }, - { - "ip": "18.230.183.15", - "port": 7002 - }, - { - "ip": "18.230.183.15", - "port": 7050 - }, - { - "ip": "18.230.183.15", - "port": 7500 - }, - { - "ip": "18.230.183.15", - "port": 8000 - }, - { - "ip": "18.230.183.15", - "port": 8002 - }, - { - "ip": "18.230.183.15", - "port": 8003 - }, - { - "ip": "18.230.183.15", - "port": 8010 - }, - { - "ip": "18.230.183.15", - "port": 8050 - }, - { - "ip": "18.230.183.15", - "port": 8700 - }, - { - "ip": "18.230.183.15", - "port": 8888 - }, - { - "ip": "18.230.183.15", - "port": 9001 - }, - { - "ip": "18.230.183.15", - "port": 9005 - }, - { - "ip": "18.230.183.15", - "port": 9006 - }, - { - "ip": "18.230.183.15", - "port": 9007 - }, - { - "ip": "18.230.183.15", - "port": 9008 - }, - { - "ip": "18.230.183.15", - "port": 9011 - }, - { - "ip": "18.230.183.15", - "port": 9999 - }, - { - "ip": "18.230.183.15", - "port": 30000 - }, - { - "ip": "79.170.66.244", - "port": 80 - }, - { - "ip": "79.170.66.244", - "port": 443 - }, - { - "ip": "142.93.143.209", - "port": 80 - }, - { - "ip": "142.93.143.209", - "port": 443 - }, - { - "ip": "52.17.105.88", - "port": 80 - }, - { - "ip": "52.17.105.88", - "port": 443 - }, - { - "ip": "52.17.105.88", - "port": 8002 - }, - { - "ip": "52.17.105.88", - "port": 8011 - }, - { - "ip": "52.17.105.88", - "port": 8080 - }, - { - "ip": "52.17.105.88", - "port": 8090 - }, - { - "ip": "52.17.105.88", - "port": 8100 - }, - { - "ip": "52.17.105.88", - "port": 8200 - }, - { - "ip": "52.17.105.88", - "port": 8300 - }, - { - "ip": "52.17.105.88", - "port": 9000 - }, - { - "ip": "52.17.105.88", - "port": 9006 - }, - { - "ip": "52.17.105.88", - "port": 9042 - }, - { - "ip": "52.17.105.88", - "port": 9090 - }, - { - "ip": "52.17.105.88", - "port": 44002 - }, - { - "ip": "52.17.105.88", - "port": 46000 - }, - { - "ip": "52.17.105.88", - "port": 50001 - }, - { - "ip": "52.17.105.88", - "port": 50002 - }, - { - "ip": "101.201.155.187", - "port": 80 - }, - { - "ip": "101.201.155.187", - "port": 443 - }, - { - "ip": "101.201.155.187", - "port": 3089 - }, - { - "ip": "51.105.230.128", - "port": 80 - }, - { - "ip": "51.105.230.128", - "port": 443 - }, - { - "ip": "51.105.230.128", - "port": 9443 - }, - { - "ip": "172.104.195.252", - "port": 80 - }, - { - "ip": "172.104.195.252", - "port": 443 - }, - { - "ip": "172.104.195.252", - "port": 3000 - }, - { - "ip": "172.104.195.252", - "port": 4000 - }, - { - "ip": "51.15.109.210", - "port": 80 - }, - { - "ip": "51.15.109.210", - "port": 443 - }, - { - "ip": "51.15.109.210", - "port": 3123 - }, - { - "ip": "51.15.109.210", - "port": 5555 - }, - { - "ip": "51.15.109.210", - "port": 8001 - }, - { - "ip": "51.15.109.210", - "port": 8088 - }, - { - "ip": "51.15.109.210", - "port": 9001 - }, - { - "ip": "51.15.109.210", - "port": 9996 - }, - { - "ip": "51.15.109.210", - "port": 9998 - }, - { - "ip": "116.203.91.41", - "port": 80 - }, - { - "ip": "116.203.91.41", - "port": 443 - }, - { - "ip": "116.203.91.41", - "port": 8080 - }, - { - "ip": "45.76.173.71", - "port": 8080 - }, - { - "ip": "72.249.124.222", - "port": 80 - }, - { - "ip": "72.249.124.222", - "port": 443 - }, - { - "ip": "72.249.124.222", - "port": 8080 - }, - { - "ip": "72.249.124.222", - "port": 8081 - }, - { - "ip": "142.93.181.65", - "port": 80 - }, - { - "ip": "142.93.181.65", - "port": 443 - }, - { - "ip": "91.134.138.76", - "port": 80 - }, - { - "ip": "91.134.138.76", - "port": 443 - }, - { - "ip": "91.134.138.76", - "port": 8080 - }, - { - "ip": "167.172.192.83", - "port": 80 - }, - { - "ip": "167.172.192.83", - "port": 443 - }, - { - "ip": "137.184.34.216", - "port": 80 - }, - { - "ip": "137.184.34.216", - "port": 443 - }, - { - "ip": "137.184.34.216", - "port": 8200 - }, - { - "ip": "161.97.80.29", - "port": 80 - }, - { - "ip": "161.97.80.29", - "port": 443 - }, - { - "ip": "161.97.80.29", - "port": 6697 - }, - { - "ip": "43.200.214.123", - "port": 80 - }, - { - "ip": "43.200.214.123", - "port": 443 - }, - { - "ip": "18.134.141.89", - "port": 80 - }, - { - "ip": "18.134.141.89", - "port": 443 - }, - { - "ip": "18.134.141.89", - "port": 8111 - }, - { - "ip": "87.239.109.138", - "port": 443 - }, - { - "ip": "13.37.91.209", - "port": 8080 - }, - { - "ip": "41.213.202.40", - "port": 80 - }, - { - "ip": "41.213.202.40", - "port": 443 - }, - { - "ip": "41.213.202.40", - "port": 3000 - }, - { - "ip": "41.213.202.40", - "port": 8086 - }, - { - "ip": "41.213.202.40", - "port": 8087 - }, - { - "ip": "41.213.202.40", - "port": 8089 - }, - { - "ip": "41.213.202.40", - "port": 8090 - }, - { - "ip": "41.213.202.40", - "port": 8091 - }, - { - "ip": "41.213.202.40", - "port": 8092 - }, - { - "ip": "41.213.202.40", - "port": 8093 - }, - { - "ip": "41.213.202.40", - "port": 8094 - }, - { - "ip": "41.213.202.40", - "port": 8095 - }, - { - "ip": "41.213.202.40", - "port": 8096 - }, - { - "ip": "41.213.202.40", - "port": 8097 - }, - { - "ip": "41.213.202.40", - "port": 8099 - }, - { - "ip": "41.213.202.40", - "port": 8100 - }, - { - "ip": "41.213.202.40", - "port": 8761 - }, - { - "ip": "41.213.202.40", - "port": 8888 - }, - { - "ip": "41.213.202.40", - "port": 9000 - }, - { - "ip": "45.32.194.136", - "port": 80 - }, - { - "ip": "45.32.194.136", - "port": 443 - }, - { - "ip": "45.32.194.136", - "port": 8080 - }, - { - "ip": "51.178.65.136", - "port": 80 - }, - { - "ip": "51.178.65.136", - "port": 443 - }, - { - "ip": "51.178.65.136", - "port": 914 - }, - { - "ip": "51.178.65.136", - "port": 918 - }, - { - "ip": "51.178.65.136", - "port": 920 - }, - { - "ip": "51.178.65.136", - "port": 923 - }, - { - "ip": "51.178.65.136", - "port": 924 - }, - { - "ip": "51.178.65.136", - "port": 925 - }, - { - "ip": "51.178.65.136", - "port": 943 - }, - { - "ip": "51.178.65.136", - "port": 1194 - }, - { - "ip": "51.178.65.136", - "port": 3111 - }, - { - "ip": "51.178.65.136", - "port": 5000 - }, - { - "ip": "51.178.65.136", - "port": 5002 - }, - { - "ip": "51.178.65.136", - "port": 5003 - }, - { - "ip": "51.178.65.136", - "port": 5004 - }, - { - "ip": "51.178.65.136", - "port": 5005 - }, - { - "ip": "51.178.65.136", - "port": 8075 - }, - { - "ip": "51.178.65.136", - "port": 8080 - }, - { - "ip": "51.178.65.136", - "port": 8081 - }, - { - "ip": "54.76.48.76", - "port": 80 - }, - { - "ip": "54.76.48.76", - "port": 443 - }, - { - "ip": "43.200.218.224", - "port": 80 - }, - { - "ip": "43.200.218.224", - "port": 443 - }, - { - "ip": "109.120.183.110", - "port": 80 - }, - { - "ip": "109.120.183.110", - "port": 443 - }, - { - "ip": "46.101.69.95", - "port": 443 - }, - { - "ip": "54.174.186.80", - "port": 80 - }, - { - "ip": "54.174.186.80", - "port": 443 - }, - { - "ip": "62.171.159.154", - "port": 80 - }, - { - "ip": "62.171.159.154", - "port": 443 - }, - { - "ip": "62.171.159.154", - "port": 3020 - }, - { - "ip": "62.171.159.154", - "port": 3030 - }, - { - "ip": "62.171.159.154", - "port": 4000 - }, - { - "ip": "62.171.159.154", - "port": 8081 - }, - { - "ip": "62.171.159.154", - "port": 9983 - }, - { - "ip": "62.171.159.154", - "port": 10000 - }, - { - "ip": "99.80.119.119", - "port": 443 - }, - { - "ip": "52.40.219.158", - "port": 80 - }, - { - "ip": "52.40.219.158", - "port": 443 - }, - { - "ip": "52.168.104.101", - "port": 80 - }, - { - "ip": "52.168.104.101", - "port": 8080 - }, - { - "ip": "52.213.239.216", - "port": 80 - }, - { - "ip": "52.213.239.216", - "port": 443 - }, - { - "ip": "52.213.239.216", - "port": 3000 - }, - { - "ip": "52.213.239.216", - "port": 8002 - }, - { - "ip": "52.213.239.216", - "port": 8011 - }, - { - "ip": "52.213.239.216", - "port": 8080 - }, - { - "ip": "52.213.239.216", - "port": 8090 - }, - { - "ip": "52.213.239.216", - "port": 8100 - }, - { - "ip": "52.213.239.216", - "port": 8200 - }, - { - "ip": "52.213.239.216", - "port": 8300 - }, - { - "ip": "52.213.239.216", - "port": 9000 - }, - { - "ip": "52.213.239.216", - "port": 9006 - }, - { - "ip": "52.213.239.216", - "port": 9042 - }, - { - "ip": "52.213.239.216", - "port": 9090 - }, - { - "ip": "52.213.239.216", - "port": 43003 - }, - { - "ip": "52.213.239.216", - "port": 45000 - }, - { - "ip": "52.213.239.216", - "port": 46000 - }, - { - "ip": "52.213.239.216", - "port": 47000 - }, - { - "ip": "52.213.239.216", - "port": 50001 - }, - { - "ip": "52.213.239.216", - "port": 50002 - }, - { - "ip": "118.27.2.237", - "port": 80 - }, - { - "ip": "118.27.2.237", - "port": 443 - }, - { - "ip": "103.148.198.3", - "port": 80 - }, - { - "ip": "103.148.198.3", - "port": 81 - }, - { - "ip": "103.148.198.3", - "port": 443 - }, - { - "ip": "103.148.198.3", - "port": 8812 - }, - { - "ip": "103.148.198.3", - "port": 9999 - }, - { - "ip": "157.245.139.172", - "port": 443 - }, - { - "ip": "52.47.202.74", - "port": 80 - }, - { - "ip": "52.47.202.74", - "port": 443 - }, - { - "ip": "52.68.66.2", - "port": 80 - }, - { - "ip": "52.68.66.2", - "port": 443 - }, - { - "ip": "54.84.117.50", - "port": 443 - }, - { - "ip": "54.84.117.50", - "port": 3001 - }, - { - "ip": "162.253.18.21", - "port": 80 - }, - { - "ip": "162.253.18.21", - "port": 443 - }, - { - "ip": "13.48.180.216", - "port": 443 - }, - { - "ip": "13.48.180.216", - "port": 444 - }, - { - "ip": "35.176.117.115", - "port": 443 - }, - { - "ip": "184.73.212.148", - "port": 443 - }, - { - "ip": "184.73.212.148", - "port": 3001 - }, - { - "ip": "46.101.118.222", - "port": 80 - }, - { - "ip": "46.101.118.222", - "port": 443 - }, - { - "ip": "46.101.118.222", - "port": 5000 - }, - { - "ip": "46.101.118.222", - "port": 5555 - }, - { - "ip": "46.101.118.222", - "port": 7777 - }, - { - "ip": "46.101.118.222", - "port": 8080 - }, - { - "ip": "46.101.118.222", - "port": 8083 - }, - { - "ip": "46.101.118.222", - "port": 8443 - }, - { - "ip": "46.101.118.222", - "port": 8888 - }, - { - "ip": "46.101.118.222", - "port": 9917 - }, - { - "ip": "52.143.181.223", - "port": 80 - }, - { - "ip": "52.143.181.223", - "port": 443 - }, - { - "ip": "52.143.181.223", - "port": 8443 - }, - { - "ip": "154.40.49.153", - "port": 80 - }, - { - "ip": "154.40.49.153", - "port": 443 - }, - { - "ip": "154.40.49.153", - "port": 888 - }, - { - "ip": "154.40.49.153", - "port": 8443 - }, - { - "ip": "154.40.49.153", - "port": 12345 - }, - { - "ip": "185.64.247.200", - "port": 80 - }, - { - "ip": "185.64.247.200", - "port": 7200 - }, - { - "ip": "18.163.69.248", - "port": 80 - }, - { - "ip": "18.163.69.248", - "port": 443 - }, - { - "ip": "18.163.69.248", - "port": 7080 - }, - { - "ip": "18.163.69.248", - "port": 9060 - }, - { - "ip": "18.163.69.248", - "port": 9080 - }, - { - "ip": "52.35.32.148", - "port": 80 - }, - { - "ip": "52.35.32.148", - "port": 443 - }, - { - "ip": "35.238.236.100", - "port": 80 - }, - { - "ip": "35.238.236.100", - "port": 443 - }, - { - "ip": "35.238.236.100", - "port": 4241 - }, - { - "ip": "54.69.122.58", - "port": 80 - }, - { - "ip": "54.69.122.58", - "port": 443 - }, - { - "ip": "2001:19F0:0005:1996:5400:03FF:FE22:1F29", - "port": 80 - }, - { - "ip": "2001:19F0:0005:1996:5400:03FF:FE22:1F29", - "port": 443 - }, - { - "ip": "52.49.26.241", - "port": 15443 - }, - { - "ip": "34.216.179.64", - "port": 80 - }, - { - "ip": "34.216.179.64", - "port": 443 - }, - { - "ip": "34.225.9.67", - "port": 443 - }, - { - "ip": "162.243.198.20", - "port": 80 - }, - { - "ip": "162.243.198.20", - "port": 443 - }, - { - "ip": "130.211.121.168", - "port": 80 - }, - { - "ip": "130.211.121.168", - "port": 443 - }, - { - "ip": "3.127.76.98", - "port": 80 - }, - { - "ip": "3.127.76.98", - "port": 443 - }, - { - "ip": "52.221.199.147", - "port": 443 - }, - { - "ip": "52.221.199.147", - "port": 3000 - }, - { - "ip": "52.221.199.147", - "port": 5000 - }, - { - "ip": "52.221.199.147", - "port": 8443 - }, - { - "ip": "106.2.69.41", - "port": 80 - }, - { - "ip": "106.2.69.41", - "port": 443 - }, - { - "ip": "178.251.71.109", - "port": 80 - }, - { - "ip": "178.251.71.109", - "port": 443 - }, - { - "ip": "178.251.71.109", - "port": 3001 - }, - { - "ip": "178.251.71.109", - "port": 3002 - }, - { - "ip": "178.251.71.109", - "port": 3003 - }, - { - "ip": "178.251.71.109", - "port": 8089 - }, - { - "ip": "35.205.27.75", - "port": 80 - }, - { - "ip": "35.205.27.75", - "port": 443 - }, - { - "ip": "35.205.27.75", - "port": 8443 - }, - { - "ip": "54.76.34.116", - "port": 80 - }, - { - "ip": "54.76.34.116", - "port": 443 - }, - { - "ip": "54.76.34.116", - "port": 3000 - }, - { - "ip": "54.76.34.116", - "port": 8002 - }, - { - "ip": "54.76.34.116", - "port": 8011 - }, - { - "ip": "54.76.34.116", - "port": 8080 - }, - { - "ip": "54.76.34.116", - "port": 8090 - }, - { - "ip": "54.76.34.116", - "port": 8100 - }, - { - "ip": "54.76.34.116", - "port": 8200 - }, - { - "ip": "54.76.34.116", - "port": 9000 - }, - { - "ip": "54.76.34.116", - "port": 9006 - }, - { - "ip": "54.76.34.116", - "port": 9042 - }, - { - "ip": "54.76.34.116", - "port": 9090 - }, - { - "ip": "54.76.34.116", - "port": 45000 - }, - { - "ip": "54.76.34.116", - "port": 46000 - }, - { - "ip": "54.76.34.116", - "port": 47000 - }, - { - "ip": "54.76.34.116", - "port": 50001 - }, - { - "ip": "54.76.34.116", - "port": 50002 - }, - { - "ip": "37.252.121.160", - "port": 80 - }, - { - "ip": "37.252.121.160", - "port": 443 - }, - { - "ip": "37.252.121.160", - "port": 9090 - }, - { - "ip": "62.171.161.89", - "port": 80 - }, - { - "ip": "62.171.161.89", - "port": 443 - }, - { - "ip": "62.171.161.89", - "port": 7080 - }, - { - "ip": "62.171.161.89", - "port": 7081 - }, - { - "ip": "62.171.161.89", - "port": 8084 - }, - { - "ip": "62.171.161.89", - "port": 8443 - }, - { - "ip": "62.171.161.89", - "port": 8880 - }, - { - "ip": "185.125.218.206", - "port": 80 - }, - { - "ip": "185.125.218.206", - "port": 443 - }, - { - "ip": "185.125.218.206", - "port": 8081 - }, - { - "ip": "185.125.218.206", - "port": 8085 - }, - { - "ip": "185.125.218.206", - "port": 8088 - }, - { - "ip": "137.184.80.33", - "port": 80 - }, - { - "ip": "137.184.80.33", - "port": 443 - }, - { - "ip": "15.237.111.172", - "port": 80 - }, - { - "ip": "15.237.111.172", - "port": 443 - }, - { - "ip": "15.237.111.172", - "port": 8080 - }, - { - "ip": "3.141.165.60", - "port": 80 - }, - { - "ip": "3.141.165.60", - "port": 443 - }, - { - "ip": "64.227.144.238", - "port": 80 - }, - { - "ip": "64.227.144.238", - "port": 443 - }, - { - "ip": "144.217.215.206", - "port": 443 - }, - { - "ip": "185.208.226.182", - "port": 80 - }, - { - "ip": "185.208.226.182", - "port": 443 - }, - { - "ip": "185.208.226.182", - "port": 8080 - }, - { - "ip": "185.208.226.182", - "port": 8081 - }, - { - "ip": "185.208.226.182", - "port": 9966 - }, - { - "ip": "185.208.226.182", - "port": 9968 - }, - { - "ip": "185.208.226.182", - "port": 9969 - }, - { - "ip": "185.208.226.182", - "port": 9970 - }, - { - "ip": "185.208.226.182", - "port": 9972 - }, - { - "ip": "185.208.226.182", - "port": 9973 - }, - { - "ip": "185.208.226.182", - "port": 9974 - }, - { - "ip": "185.208.226.182", - "port": 9975 - }, - { - "ip": "185.208.226.182", - "port": 9979 - }, - { - "ip": "37.200.66.18", - "port": 433 - }, - { - "ip": "37.200.66.18", - "port": 443 - }, - { - "ip": "37.200.66.18", - "port": 3000 - }, - { - "ip": "37.200.66.18", - "port": 9051 - }, - { - "ip": "188.166.112.113", - "port": 80 - }, - { - "ip": "188.166.112.113", - "port": 443 - }, - { - "ip": "188.166.112.113", - "port": 1234 - }, - { - "ip": "34.223.153.27", - "port": 80 - }, - { - "ip": "34.223.153.27", - "port": 443 - }, - { - "ip": "54.145.202.199", - "port": 80 - }, - { - "ip": "54.145.202.199", - "port": 443 - }, - { - "ip": "54.145.202.199", - "port": 3000 - }, - { - "ip": "54.145.202.199", - "port": 9100 - }, - { - "ip": "37.187.53.116", - "port": 80 - }, - { - "ip": "37.187.53.116", - "port": 2020 - }, - { - "ip": "37.187.53.116", - "port": 8080 - }, - { - "ip": "167.71.51.236", - "port": 80 - }, - { - "ip": "167.71.51.236", - "port": 8080 - } -] \ No newline at end of file diff --git a/anify-backend/src/helper/queue.ts b/anify-backend/src/helper/queue.ts deleted file mode 100644 index 7870abc..0000000 --- a/anify-backend/src/helper/queue.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { setIntervalImmediately } from "./"; - -export default class QueueExecutor { - id: string; - private intervalId: NodeJS.Timer | undefined; - private intervalN: number | undefined; - private executorFunc: ((args: T, meta: any) => Promise) | undefined; - private callbackFunc: ((args: T) => Promise | void) | undefined; - private errorFunc: ((error: Error, args: T) => Promise | void) | undefined; - private runConditionFunc: (() => boolean) | undefined; - - private queue: Set = new Set(); - private metaMap: Map = new Map(); - private paused = false; - private activeBySwitch = false; - private active = true; - private isExecuteAfterDone = false; - private running = false; - private isSelfRunning = false; - - constructor(id: string) { - this.id = id; - } - - selfRunning(): QueueExecutor { - this.isSelfRunning = true; - - return this; - } - - interval(n: number): QueueExecutor { - this.intervalN = n; - - return this; - } - - executor(func: (args: T, meta: any) => Promise): QueueExecutor { - this.executorFunc = func; - - return this; - } - - callback(func: (args: T) => Promise | void): QueueExecutor { - this.callbackFunc = func; - - return this; - } - - error(func: (error: Error, args: T) => Promise | void): QueueExecutor { - this.errorFunc = func; - - return this; - } - - add(arg: T, meta: any = undefined) { - this.queue.add(arg); - if (meta) { - this.metaMap.set(arg, meta); - } - } - - executeAfterDone(): QueueExecutor { - this.isExecuteAfterDone = true; - - return this; - } - - runCondition(func: () => boolean): QueueExecutor { - this.runConditionFunc = func; - - return this; - } - - deactivate() { - this.active = false; - - return this; - } - - activate() { - this.active = true; - - return this; - } - - activateBySwitch() { - this.activeBySwitch = true; - - return this; - } - - start() { - if (!this.intervalN || !this.executorFunc) throw new Error("Both interval and executor function need to be supplied"); - - this.intervalId = setIntervalImmediately(async () => { - if (this.paused || (this.queue.size <= 0 && !this.activeBySwitch && !this.isSelfRunning)) return; - if (this.runConditionFunc && !this.runConditionFunc()) return; - if (this.isExecuteAfterDone && this.running) return; - - if (this.activeBySwitch) { - if (this.active) { - this.running = true; - if (this.executorFunc) - this.executorFunc(true as any, undefined) - .then((_) => { - if (this.callbackFunc) this.callbackFunc(true as any); - this.running = false; - }) - .catch((err) => { - if (this.errorFunc) this.errorFunc(err, true as any); - this.running = false; - }); - } - } else { - if (this.isSelfRunning) { - if (this.executorFunc) - this.executorFunc(undefined as T, undefined) - .then((_) => { - if (this.callbackFunc) this.callbackFunc(undefined as T); - this.running = false; - }) - .catch((err) => { - if (this.errorFunc) this.errorFunc(err, undefined as T); - this.running = false; - }); - } else { - const value = this.queue.values().next().value; - if (value) { - const meta = this.metaMap.get(value); - this.queue.delete(value); - this.metaMap.delete(value); - this.running = true; - if (this.executorFunc) - this.executorFunc(value, meta) - .then((_) => { - if (this.callbackFunc) this.callbackFunc(value); - this.running = false; - }) - .catch((err) => { - if (this.errorFunc) this.errorFunc(err, value); - this.running = false; - }); - } - } - } - }, this.intervalN); - - return this; - } - - pause() { - this.paused = true; - } - - unpause() { - this.paused = false; - } - - destroy() { - this.queue.clear(); - clearInterval(this.intervalId); - } -} diff --git a/anify-backend-recode/src/helper/request.ts b/anify-backend/src/helper/request.ts similarity index 100% rename from anify-backend-recode/src/helper/request.ts rename to anify-backend/src/helper/request.ts diff --git a/anify-backend/src/helper/stringSimilarity.ts b/anify-backend/src/helper/stringSimilarity.ts index f7e0289..81bc234 100644 --- a/anify-backend/src/helper/stringSimilarity.ts +++ b/anify-backend/src/helper/stringSimilarity.ts @@ -1,4 +1,26 @@ -import { clean } from "./title"; +import { clean, sanitizeTitle } from "./title"; + +export function similarity(externalTitle: string, title: string, titleArray: string[] = []): { same: boolean; value: number } { + if (!title) { + title = ""; + } + let simi = compareTwoStrings(sanitizeTitle(title.toLowerCase()), externalTitle.toLowerCase()); + titleArray.forEach((el) => { + if (el) { + const tempSimi = compareTwoStrings(title.toLowerCase(), el.toLowerCase()); + if (tempSimi > simi) simi = tempSimi; + } + }); + let found = false; + if (simi > 0.6) { + found = true; + } + + return { + same: found, + value: simi, + }; +} // From npm package string-similarity export function compareTwoStrings(first: string, second: string): number { diff --git a/anify-backend/src/helper/title.ts b/anify-backend/src/helper/title.ts index 4178a07..33b6dcd 100644 --- a/anify-backend/src/helper/title.ts +++ b/anify-backend/src/helper/title.ts @@ -8,8 +8,8 @@ export function clean(title: string) { .replaceAll("season", "") .replaceAll(" ", " ") .replaceAll('"', "") - .trimEnd() - ) + .trimEnd(), + ), ); } @@ -23,3 +23,99 @@ export function removeSpecialChars(title: string) { export function transformSpecificVariations(title: string) { return title?.replaceAll("yuu", "yu").replaceAll(" ou", " oh"); } + +export function sanitizeTitle(title: string): string { + let resTitle = title.replace(/ *(\(dub\)|\(sub\)|\(uncensored\)|\(uncut\)|\(subbed\)|\(dubbed\))/i, ""); + resTitle = resTitle.replace(/ *\([^)]+audio\)/i, ""); + resTitle = resTitle.replace(/ BD( |$)/i, ""); + resTitle = resTitle.replace(/\(TV\)/g, ""); + resTitle = resTitle.trim(); + resTitle = resTitle.substring(0, 99); // truncate + return resTitle; +} + +export const slugify = (...args: (string | number)[]): string => { + const defaultReplacements = [ + ["[aàáâãäåāăąǻάαа]", "a"], + ["[bбḃ]", "b"], + ["[cçćĉċčћ]", "c"], + ["[dðďđδдђḋ]", "d"], + ["[eèéêëēĕėęěέεеэѐё]", "e"], + ["[fƒφфḟ]", "f"], + ["[gĝğġģγгѓґ]", "g"], + ["[hĥħ]", "h"], + ["[iìíîïĩīĭįıΐήίηιϊийіїѝ]", "i"], + ["[jĵј]", "j"], + ["[kķĸκкќ]", "k"], + ["[lĺļľŀłλл]", "l"], + ["[mμмṁ]", "m"], + ["[nñńņňʼnŋνн]", "n"], + ["[oòóôõöōŏőοωόώо]", "o"], + ["[pπпṗ]", "p"], + ["q", "q"], + ["[rŕŗřρр]", "r"], + ["[sśŝşšſșςσсṡ]", "s"], + ["[tţťŧțτтṫ]", "t"], + ["[uùúûüũūŭůűųуў]", "u"], + ["[vβв]", "v"], + ["[wŵẁẃẅ]", "w"], + ["[xξ]", "x"], + ["[yýÿŷΰυϋύыỳ]", "y"], + ["[zźżžζз]", "z"], + ["[æǽ]", "ae"], + ["[χч]", "ch"], + ["[ѕџ]", "dz"], + ["fi", "fi"], + ["fl", "fl"], + ["я", "ia"], + ["[ъє]", "ie"], + ["ij", "ij"], + ["ю", "iu"], + ["х", "kh"], + ["љ", "lj"], + ["њ", "nj"], + ["[øœǿ]", "oe"], + ["ψ", "ps"], + ["ш", "sh"], + ["щ", "shch"], + ["ß", "ss"], + ["[þθ]", "th"], + ["ц", "ts"], + ["ж", "zh"], + + // White_Space, General_Category=Dash_Punctuation and Control Codes + ["[\\u0009-\\u000D\\u001C-\\u001F\\u0020\\u002D\\u0085\\u00A0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000\\u058A\\u05BE\\u1400\\u1806\\u2010-\\u2015\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D]", "-"], + ]; + + const replaceLoweringCase = (string: string, [regExp, replacement]: any) => string.replace(RegExp(regExp, "giu"), replacement); + + let value = args.join(" "); + + defaultReplacements.forEach(([a, b]) => { + value = replaceLoweringCase(value, [a, b]); + }); + + return value + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "-") + .toLowerCase() + .trim() + .replace(/[^a-z0-9 ]/g, "-") + .replace(/\s+/g, "-"); +}; + +export function stringSearch(string: string, pattern: string): number { + let count = 0; + string = string.toLowerCase(); + pattern = pattern.toLowerCase(); + string = string.replace(/[^a-zA-Z0-9 -]/g, ""); + pattern = pattern.replace(/[^a-zA-Z0-9 -]/g, ""); + + for (let i = 0; i < string.length; i++) { + for (let j = 0; j < pattern.length; j++) { + if (pattern[j] !== string[i + j]) break; + if (j === pattern.length - 1) count++; + } + } + return count; +} diff --git a/anify-backend/src/index.ts b/anify-backend/src/index.ts index 4e9c720..3d5216f 100644 --- a/anify-backend/src/index.ts +++ b/anify-backend/src/index.ts @@ -1,86 +1,94 @@ import dotenv from "dotenv"; dotenv.config(); +import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; +import { Format, MediaStatus, Type } from "./types/enums"; +import { init } from "./database"; +import emitter, { Events } from "./lib"; +import { get } from "./database/impl/modify/get"; import queues from "./worker"; -import emitter, { Events } from "./helper/event"; import { start } from "./server"; -import Database from "./database"; -import { MediaStatus } from "./mapping"; -import { fetchCorsProxies } from "./helper/proxies"; +import { mangaProviders } from "./mappings"; +import { loadPDF } from "./lib/impl/pdf"; +import { loadMapping } from "./lib/impl/mappings"; +import { fetchChapters } from "./content/impl/chapters"; -emitter.on(Events.COMPLETED_SEASONAL_LOAD, async (data) => { - for (let i = 0; i < data.trending.length; i++) { - if (data.trending[i].status === MediaStatus.NOT_YET_RELEASED) { - continue; - } - const existing = await Database.info(String(data.trending[i].aniListId)); - if (!existing) { - queues.mappingQueue.add({ id: data.trending[i].aniListId, type: data.trending[i].type }); - } - } - - for (let i = 0; i < data.popular.length; i++) { - if (data.popular[i].status === MediaStatus.NOT_YET_RELEASED) { - continue; - } - const existing = await Database.info(String(data.popular[i].aniListId)); - if (!existing) queues.mappingQueue.add({ id: data.popular[i].aniListId, type: data.popular[i].type }); - } +before().then(async (_) => { + //await start(); + const chapter = { + id: "/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1", + title: "Chapter 1", + number: 1, + updatedAt: 1660688888000, + }; - for (let i = 0; i < data.top.length; i++) { - if (data.top[i].status === MediaStatus.NOT_YET_RELEASED) { - continue; - } - const existing = await Database.info(String(data.top[i].aniListId)); - if (!existing) queues.mappingQueue.add({ id: data.top[i].aniListId, type: data.top[i].type }); - } + const pages = await mangaProviders.mangasee.fetchPages("/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1"); - for (let i = 0; i < data.seasonal.length; i++) { - if (data.seasonal[i].status === MediaStatus.NOT_YET_RELEASED) { - continue; - } - const existing = await Database.info(String(data.seasonal[i].aniListId)); - if (!existing) queues.mappingQueue.add({ id: data.seasonal[i].aniListId, type: data.seasonal[i].type }); - } + await loadPDF({ id: "dc481ed5-4925-4f3c-bac1-e73f1e7ed338", providerId: "mangasee", chapter, pages: pages ?? [] }).then(console.log); }); -emitter.on(Events.COMPLETED_MAPPING_LOAD, async (data) => { - for (let i = 0; i < data.length; i++) { - if (await Database.info(String(data[i].aniListId))) { - continue; +async function before() { + await fetchCorsProxies(); + await init(); + + emitter.on(Events.COMPLETED_MAPPING_LOAD, async (data) => { + for (let i = 0; i < data.length; i++) { + if (await get(String(data[i].id))) { + continue; + } + queues.createEntry.add({ toInsert: data[i], type: data[i].type }); } - queues.createEntry.add({ toInsert: data[i], type: data[i].type }); - } -}); + }); -emitter.on(Events.COMPLETED_SEARCH_LOAD, (data) => { - if (data[0]?.aniListId) { + emitter.on(Events.COMPLETED_SEARCH_LOAD, (data) => { for (let i = 0; i < data.length; i++) { if (data[i].status === MediaStatus.NOT_YET_RELEASED) { continue; } - queues.mappingQueue.add({ id: data[i].aniListId, type: data[i].type }); + queues.mappingQueue.add({ id: data[i].id, type: data[i].type, formats: [data[i].format] }); } - } -}); + }); -// Todo: For inserting all skip times, merge the episodescrape repo so that it adds a bunch of events lol -emitter.on(Events.COMPLETED_SKIPTIMES_LOAD, (data) => { - // Do something -}); + emitter.on(Events.COMPLETED_SEASONAL_LOAD, async (data) => { + for (let i = 0; i < data.trending.length; i++) { + if (data.trending[i].status === MediaStatus.NOT_YET_RELEASED) { + continue; + } + const existing = await get(String(data.trending[i].id)); + if (!existing) { + queues.mappingQueue.add({ id: data.trending[i].id, type: data.trending[i].type, formats: [data.trending[i].format] }); + } + } -emitter.on(Events.COMPLETED_PAGE_UPLOAD, (data) => { - // Do something -}); + for (let i = 0; i < data.popular.length; i++) { + if (data.popular[i].status === MediaStatus.NOT_YET_RELEASED) { + continue; + } + const existing = await get(String(data.popular[i].id)); + if (!existing) queues.mappingQueue.add({ id: data.popular[i].id, type: data.popular[i].type, formats: [data.popular[i].format] }); + } + + for (let i = 0; i < data.top.length; i++) { + if (data.top[i].status === MediaStatus.NOT_YET_RELEASED) { + continue; + } + const existing = await get(String(data.top[i].id)); + if (!existing) queues.mappingQueue.add({ id: data.top[i].id, type: data.top[i].type, formats: [data.top[i].format] }); + } -queues.seasonQueue.start(); -queues.mappingQueue.start(); -queues.createEntry.start(); -queues.searchQueue.start(); -queues.skipTimes.start(); -queues.uploadPages.start(); + for (let i = 0; i < data.seasonal.length; i++) { + if (data.seasonal[i].status === MediaStatus.NOT_YET_RELEASED) { + continue; + } + const existing = await get(String(data.seasonal[i].id)); + if (!existing) queues.mappingQueue.add({ id: data.seasonal[i].id, type: data.seasonal[i].type, formats: [data.seasonal[i].format] }); + } + }); -fetchCorsProxies().then(async () => { - await Database.initializeDatabase(); - await start(); -}); + queues.mappingQueue.start(); + queues.createEntry.start(); + queues.searchQueue.start(); + queues.seasonalQueue.start(); + queues.skipTimes.start(); + queues.uploadPages.start(); +} diff --git a/anify-backend/src/keys/index.ts b/anify-backend/src/keys/index.ts deleted file mode 100644 index 914a9a8..0000000 --- a/anify-backend/src/keys/index.ts +++ /dev/null @@ -1,118 +0,0 @@ -import crypto from "crypto"; -import { Redis } from "ioredis"; -import Database from "../database"; -import colors from "colors"; -import { env } from "../env"; -import { execSync } from "child_process"; - -let redis = new Redis((env.REDIS_URL as string) || "redis://localhost:6379"); - -if (!env.REDIS_URL) { - redis = { - get: async () => null, - set: (): Promise<"OK"> => Promise.resolve("OK"), - on: () => Redis.prototype, - keys: async () => [], - connect: async () => void 0, - call: async () => void 0, - sadd: async () => 0, - sismember: async () => 0, - } as any; -} - -const shouldUseKeys = env.USE_API_KEYS; - -export const masterKey: string | null = env.MASTER_KEY || null; - -export const createKey = async () => { - const uniqueKey = crypto.randomBytes(16).toString("hex"); - - await Database.createAPIKey(uniqueKey); - - await redis.sadd("apikeys", uniqueKey); - - return uniqueKey; -}; - -export const importKeys = async () => { - const keys = await Database.fetchAPIKeys(); - - if (masterKey && !keys.includes(masterKey)) keys.push(masterKey); - - for (const key of keys) { - const requests = await getRequests(key); - console.log(colors.blue(key) + " - " + colors.blue(requests + "") + " requests"); - - if (await redis.sismember("apikeys", key)) continue; - await redis.sadd("apikeys", key); - } -}; - -export const flushSafely = async () => { - // Execute command redis-cli flushall - //await redis.call("flushall"); - const scripts = ["redis-cli flushall"]; - - for (const script of scripts) { - try { - console.log(`Executing script: ${script}`); - execSync(script, { stdio: "inherit" }); - } catch (error) { - console.error(colors.red(`Error executing script: ${script}`)); - console.error(error); - } - } - - await importKeys(); -}; - -export async function checkAPIKey(req: any, res: Response, next: () => void) { - if (shouldUseKeys === "true") { - try { - if (req.query.apikey) { - const key = req.query.apikey; - - if (shouldUseKeys === "true" && (await redis.sismember("apikeys", key))) { - // Increment the request count for the API key in Redis - await increaseRequests(key); - - // Continue processing the request - next(); - } else { - return new Response(JSON.stringify({ error: "Invalid API key." }), { status: 401, headers: { "Content-Type": "application/json" } }); - } - } else { - return new Response(JSON.stringify({ error: "No API key provided." }), { status: 401, headers: { "Content-Type": "application/json" } }); - } - } catch (err) { - console.error(err); - return new Response(JSON.stringify({ error: "Internal server error." }), { status: 500, headers: { "Content-Type": "application/json" } }); - } - } else { - next(); - } -} - -export async function increaseRequests(key: string): Promise { - await redis.incr(`apikey:${key}`); -} - -export async function getRequests(key: string): Promise { - return Number(await redis.get(`apikey:${key}`)); -} - -export async function updateRequests(): Promise { - const keys = await Database.fetchAPIKeys(); - for (const key of keys) { - const requests = await getRequests(key); - if (!requests || isNaN(requests)) continue; - - await Database.updateKeyRequests(key, requests); - - await redis.del(`apikey:${key}`).catch((err) => { - console.log(colors.red("Error deleting key ") + key + colors.red(" from cache.")); - }); - - console.log(colors.green("Updated key ") + key + colors.green(".")); - } -} diff --git a/anify-backend/src/lib/entry.ts b/anify-backend/src/lib/entry.ts deleted file mode 100644 index b717856..0000000 --- a/anify-backend/src/lib/entry.ts +++ /dev/null @@ -1,45 +0,0 @@ -import emitter, { Events } from "../helper/event"; -import { Anime, Format, Manga, Season, Type } from "../mapping"; -import colors from "colors"; -import Database from "../database"; - -export const createEntry = async (data: { toInsert: Anime | Manga; type: Type }) => { - const existing = await Database.info(String(data.toInsert.id)); - - if (existing) { - await emitter.emitAsync(Events.COMPLETED_ENTRY_CREATION, data.toInsert); - return existing; - } - - if (data.type === Type.ANIME) { - if (Array.isArray((data.toInsert as any).season)) { - console.log(colors.yellow("Fixed season for anime.")); - (data.toInsert as any).season = (data.toInsert as any).season[0]; - } - } - - (data.toInsert as any).id = String(data.toInsert.id); - - await Database.createEntry(data.type === Type.ANIME ? (data.toInsert as Anime) : (data.toInsert as Manga)); - - await emitter.emitAsync(Events.COMPLETED_ENTRY_CREATION, data.toInsert); - - return data.toInsert; -}; - -export const returnCreatedEntry = (data: Anime | Manga) => { - if (data.type === Type.ANIME) { - if (Array.isArray((data as any).season)) { - console.log(colors.yellow("Fixed season for anime.")); - (data as any).season = (data as any).season[0]; - } - } - - (data as any).id = String(data.id); - - if (data.type === Type.ANIME) { - return data as Anime; - } else { - return data as Manga; - } -}; diff --git a/anify-backend-recode/src/lib/executor.ts b/anify-backend/src/lib/executor.ts similarity index 100% rename from anify-backend-recode/src/lib/executor.ts rename to anify-backend/src/lib/executor.ts diff --git a/anify-backend-recode/src/lib/impl/entry.ts b/anify-backend/src/lib/impl/entry.ts similarity index 95% rename from anify-backend-recode/src/lib/impl/entry.ts rename to anify-backend/src/lib/impl/entry.ts index acae6a9..7583868 100644 --- a/anify-backend-recode/src/lib/impl/entry.ts +++ b/anify-backend/src/lib/impl/entry.ts @@ -1,7 +1,7 @@ import { get } from "../../database/impl/modify/get"; import { Type } from "../../types/enums"; import { Anime, Manga } from "../../types/types"; -import emitter, { Events } from "../"; +import emitter, { Events } from ".."; import { create } from "../../database/impl/modify/create"; export const createEntry = async (data: { toInsert: Anime | Manga; type: Type }) => { diff --git a/anify-backend-recode/src/lib/impl/mappings.ts b/anify-backend/src/lib/impl/mappings.ts similarity index 100% rename from anify-backend-recode/src/lib/impl/mappings.ts rename to anify-backend/src/lib/impl/mappings.ts diff --git a/anify-backend-recode/src/lib/impl/pdf.ts b/anify-backend/src/lib/impl/pdf.ts similarity index 100% rename from anify-backend-recode/src/lib/impl/pdf.ts rename to anify-backend/src/lib/impl/pdf.ts diff --git a/anify-backend-recode/src/lib/impl/search.ts b/anify-backend/src/lib/impl/search.ts similarity index 100% rename from anify-backend-recode/src/lib/impl/search.ts rename to anify-backend/src/lib/impl/search.ts diff --git a/anify-backend-recode/src/lib/impl/seasonal.ts b/anify-backend/src/lib/impl/seasonal.ts similarity index 100% rename from anify-backend-recode/src/lib/impl/seasonal.ts rename to anify-backend/src/lib/impl/seasonal.ts diff --git a/anify-backend-recode/src/lib/impl/skipTimes.ts b/anify-backend/src/lib/impl/skipTimes.ts similarity index 100% rename from anify-backend-recode/src/lib/impl/skipTimes.ts rename to anify-backend/src/lib/impl/skipTimes.ts diff --git a/anify-backend-recode/src/lib/index.ts b/anify-backend/src/lib/index.ts similarity index 100% rename from anify-backend-recode/src/lib/index.ts rename to anify-backend/src/lib/index.ts diff --git a/anify-backend/src/lib/mappings.ts b/anify-backend/src/lib/mappings.ts deleted file mode 100644 index 446a6c2..0000000 --- a/anify-backend/src/lib/mappings.ts +++ /dev/null @@ -1,437 +0,0 @@ -import { ANIME_PROVIDERS, Anime, Format, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, Manga, MediaStatus, Result, Season, Type, animeProviders, ProviderType, mangaProviders, metaProviders, infoProviders } from "../mapping"; -import colors from "colors"; -import AniList from "../mapping/impl/information/anilist"; -import { isString, similarity, slugify } from "../helper"; -import InformationProvider, { AnimeInfo, MangaInfo } from "../mapping/impl/information"; -import emitter, { Events } from "../helper/event"; -import Database from "../database"; -import { findBestMatch2DArray } from "../helper/stringSimilarity"; -import { clean } from "../helper/title"; -// Return a mapped result using the ID given -const aniList = new AniList(); - -export const loadMapping = async (data: { id: string; type: Type }, aniData?: AnimeInfo | MangaInfo | null, retries = 0, media?: Anime | Manga): Promise => { - const MIN_MAPPINGS = 3; - const MAX_RETRIES = 2; - - if (retries > 0) console.log(colors.yellow("Remapping ") + colors.blue(data.id) + colors.yellow(" with retry ") + colors.blue(retries + "") + colors.yellow("...")); - - if (!aniData) { - try { - // First check if exists in database - const existing = await Database.info(data.id); - - if (existing) { - // If it does, emit the event and return - await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, [existing]); - return [existing] as any; - } - } catch (e) { - console.error(e); - console.log(colors.red("Error while fetching from database.")); - } - } - - console.log(colors.gray("Loading mapping for ") + colors.blue(data.id) + colors.gray("...")); - - // Map only one media - if (!aniData) { - aniData = await aniList.getMedia(data.id); - } - - if (!aniData) { - await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, []); - return []; - } - - if ((aniData as any).isAdult) { - console.log(colors.red("Media is adult. Skipping...")); - return []; - } - if (aniData.status === MediaStatus.NOT_YET_RELEASED) { - console.log(colors.red("Media is not yet released. Skipping...")); - return []; - } - - const result = await map((aniData as any)?.type, [aniData?.format!], aniData, media); - - // Only return if the ID matches the one we're looking for - // If it isn't, we don't want to return. - for (let i = 0; i < result.length; i++) { - if (String(result[i].id) === String(data.id)) { - console.log(colors.gray("Found mapping for ") + colors.blue(data.id) + colors.gray(".") + colors.gray(" Saving...")); - await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, [result[i]]); - - // Only return if anime or manga mappings are greater than MIN_MAPPINGS. - const mappings = result[i].mappings.filter((item) => item.providerType === ProviderType.ANIME || item.providerType === ProviderType.MANGA); - - if (mappings.length < MIN_MAPPINGS && retries < MAX_RETRIES) return loadMapping(data, aniData, retries + 1, result[i]); - - return [result[i]] as Anime[] | Manga[]; - } - } - - await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, []); - return []; -}; - -// Map and insert a mapping into the database -export const insertMapping = async (data: { id: string; type: Type }, aniData: AnimeInfo | MangaInfo | undefined) => { - if ((aniData as any).isAdult) return []; - - const result = await map((aniData as any)?.type, [aniData?.format!], aniData); - - // Only return if the ID matches the one we're looking for - // If it isn't, we don't want to return. - for (let i = 0; i < result.length; i++) { - if (String(result[i].id) === String(data.id)) { - console.log(colors.gray("Found mapping for ") + colors.blue(data.id) + colors.gray(".") + colors.gray(" Saving...")); - await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, [result[i]]); - return [result[i]]; - } - } - - await emitter.emitAsync(Events.COMPLETED_MAPPING_LOAD, []); - return []; -}; - -// Map a media to AniList -export const map = async (type: Type, formats: Format[], aniData: AnimeInfo | MangaInfo | undefined, media?: Anime | Manga): Promise => { - const providers = type === Type.ANIME ? ANIME_PROVIDERS : MANGA_PROVIDERS; - providers.push(...(META_PROVIDERS as any)); - - if (media) { - aniData?.synonyms?.push(...media.synonyms); - aniData?.synonyms?.push(...(media.title.english ? [media.title.english] : [])); - aniData?.synonyms?.push(...(media.title.native ? [media.title.native] : [])); - aniData?.synonyms?.push(...(media.title.romaji ? [media.title.romaji] : [])); - - if (aniData) { - aniData.title.english = media.title.english; - aniData.title.native = media.title.native; - aniData.title.romaji = media.title.romaji; - - aniData.format = media.format; - } - } - - // Filter out providers that don't contain the format - const suitableProviders = (providers as any[]) - .filter((provider) => { - if (formats && provider.formats) { - return formats.some((format) => provider.formats.includes(format)); - } - return true; - }) - .reduce((acc, currentProvider) => { - const existingProvider = acc.find((provider) => provider.id === currentProvider.id); - if (!existingProvider) { - acc.push(currentProvider); - } - return acc; - }, []); - - // Search for the media on each provider - const promises = suitableProviders.map((provider) => { - const search = [provider.search(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native, aniData?.format, (aniData as any)?.year)]; - return Promise.all(search) - .then((results) => { - return results.find((r) => r?.length !== 0) || []; - }) - .catch((err) => { - console.log(colors.red("Error fetching from provider ") + colors.blue(provider.id) + colors.red(".")); - console.error(err); - return []; - }); - }); - - const resultsArray = await Promise.all(promises); - - const mappings: MappedResult[] = []; - - // Loop through each provider and find the best match - for (let i = 0; i < resultsArray.length; i++) { - const providerData = resultsArray[i]; - const title: string = (aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native)!; - - const providerTitles = providerData.map((m, i) => { - const titles = [m.title, ...(m.altTitles ?? [])]; - return titles; - }); - - // If there are no results, skip - if (providerTitles.length === 0) { - console.log(colors.gray("No results found for ") + colors.blue(title) + colors.gray(" on ") + colors.blue(suitableProviders[i].id) + colors.gray(".")); - continue; - } - - const titles = [aniData?.title.english, aniData?.title.romaji, aniData?.title.native].filter(isString); - const cleanedTitles = titles.map((x) => clean(x?.toLowerCase().trim() ?? "")); - - const bestMatchIndex = findBestMatch2DArray(cleanedTitles, providerTitles); - - if (bestMatchIndex.bestMatch.rating < 0.5) { - continue; - } - - const best: Result = providerData[bestMatchIndex.bestMatchIndex]; - - // Add checks - if (best.format != Format.UNKNOWN && (aniData as any)?.format && (aniData as any)?.format != Format.UNKNOWN && best.format != aniData?.format) continue; - if (best.year != 0 && (aniData as any)?.year && (aniData as any)?.year != 0 && best.year != (aniData as any)?.year) continue; - - const altTitles: any[] = Object.values((aniData as any)?.title).concat(aniData?.synonyms); - - const sim = similarity(title, best.title, altTitles); - - //if (sim.value < 0.6) continue; - if (mappings.filter((m) => m.data.id === best.id).length > 0) continue; - - mappings.push({ - id: (aniData as any).id, - malId: (aniData as any).idMal, - slug: slugify(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native ?? ""), - data: best, - similarity: sim.value, - }); - } - - // Create the media object - const result = await createMedia(mappings, type); - - console.log(colors.yellow("Finished fetching from providers.") + colors.blue(" - ") + colors.yellow(aniData?.title.english ?? aniData?.title.romaji ?? aniData?.title.native!)); - return result; -}; - -export async function createMedia(mappings: MappedResult[], type: Type): Promise { - const results: any[] = []; - - for (const mapping of mappings) { - let hasPushed = false; - const providerType: ProviderType | null = animeProviders[mapping.data.providerId]?.providerType ? ProviderType.ANIME : mangaProviders[mapping.data.providerId]?.providerType ? ProviderType.MANGA : metaProviders[mapping.data.providerId]?.providerType ? ProviderType.META : infoProviders[mapping.data.providerId]?.providerType ? ProviderType.INFORMATION : null; - - for (const result of results) { - if (result.id === mapping.id) { - hasPushed = true; - - const toPush = { - id: mapping.data.id, - providerId: mapping.data.providerId, - providerType, - similarity: mapping.similarity, - }; - - result.mappings.push(toPush); - } - } - - if (!hasPushed) { - if (type === Type.ANIME) { - const anime: Anime = { - id: mapping.id, - slug: mapping.slug, - coverImage: "", - bannerImage: "", - trailer: "", - status: null, - type: Type.ANIME, - season: Season.UNKNOWN, - title: { - romaji: null, - english: null, - native: null, - }, - currentEpisode: null, - mappings: [ - { - id: mapping.data.id, - providerId: mapping.data.providerId, - providerType, - similarity: mapping.similarity, - }, - ], - synonyms: [], - countryOfOrigin: null, - description: null, - duration: null, - color: null, - year: null, - rating: { - anilist: 0, - mal: 0, - kitsu: 0, - }, - popularity: { - anilist: 0, - mal: 0, - kitsu: 0, - }, - genres: [], - format: Format.UNKNOWN, - relations: [], - totalEpisodes: 0, - episodes: { - latest: { - updatedAt: new Date(Date.now()).getTime(), - latestEpisode: 0, - latestTitle: "", - }, - data: [], - }, - tags: [], - artwork: [], - characters: [], - }; - - if (mapping.malId) anime.mappings.push({ id: String(mapping.malId), providerId: "mal", providerType: ProviderType.META, similarity: 1 }); - - results.push(anime); - } else { - const manga: Manga = { - id: mapping.id, - slug: mapping.slug, - coverImage: "", - bannerImage: "", - status: null, - type: Type.MANGA, - title: { - romaji: null, - english: null, - native: null, - }, - mappings: [ - { - id: mapping.data.id, - providerId: mapping.data.providerId, - providerType, - similarity: mapping.similarity, - }, - ], - synonyms: [], - countryOfOrigin: null, - description: null, - color: null, - year: null, - rating: { - anilist: 0, - mal: 0, - kitsu: 0, - }, - popularity: { - anilist: 0, - mal: 0, - kitsu: 0, - }, - genres: [], - format: Format.UNKNOWN, - relations: [], - totalChapters: 0, - totalVolumes: 0, - chapters: { - latest: { - updatedAt: new Date(Date.now()).getTime(), - latestChapter: 0, - latestTitle: "", - }, - data: [], - }, - tags: [], - artwork: [], - characters: [], - }; - - if (mapping.malId) manga.mappings.push({ id: String(mapping.malId), providerId: "mal", providerType: ProviderType.META, similarity: 1 }); - - results.push(manga); - } - } - } - - for (let i = 0; i < results.length; i++) { - const media = results[i]; - - for (let j = 0; j < INFORMATION_PROVIDERS.length; j++) { - const provider = INFORMATION_PROVIDERS[j]; - // Fetch info baesd on the media - const info = await provider.info(media).catch((err) => { - console.log(colors.red(`Error while fetching info for ${media.id} from ${provider.id}`)); - console.error(err); - return null; - }); - - if (!info) { - continue; - } - - // Fill the media object with all necessary info - fillMediaInfo(media, info, provider); - } - } - - return results; -} - -function fillMediaInfo(media: T, info: U, provider: InformationProvider): T { - try { - // Fields that need to be cross loaded. For example, rating which contains Kitsu, AniList, and MAL fields. - const crossLoadFields: (keyof AnimeInfo | MangaInfo)[] = ["popularity", "rating"]; - - // TODO: Comment needs to be written here - const specialLoadFields: (keyof AnimeInfo | MangaInfo)[] = ["title"]; - - for (const ak of Object.keys(info)) { - if (crossLoadFields.includes(ak as any) || provider.sharedArea.includes(ak as any) || specialLoadFields.includes(ak as any)) continue; - - const v = media[ak as keyof (Anime | Manga)]; - - let write = false; - if ((!v || v === "UNKNOWN") && !!info[ak as keyof (AnimeInfo | MangaInfo)] && info[ak as keyof (AnimeInfo | MangaInfo)] !== "UNKNOWN") { - write = true; - } else { - if (provider.priorityArea.includes(ak as any) && !!info[ak as keyof (AnimeInfo | MangaInfo)]) write = true; - } - - if (write) media[ak as any] = info[ak as keyof (AnimeInfo | MangaInfo)]; - } - - for (const special of specialLoadFields) { - const v = info[special as keyof (AnimeInfo | MangaInfo)]; - - if (v) { - for (const [ak, av] of Object.entries(v)) { - if (av && (av as any)?.length) { - media[special as any][ak] = av; - } - } - } - } - - for (const shared of provider.sharedArea) { - if (!media[shared as any]) { - media[shared as any] = []; - } - - media[shared as any] = [...new Set(media[shared as any].concat(info[shared as keyof (AnimeInfo | MangaInfo)] ?? []))]; - } - - for (const crossLoad of crossLoadFields) { - if (info[crossLoad as keyof (AnimeInfo | MangaInfo)]) { - media[crossLoad as any][provider.id] = info[crossLoad as keyof (AnimeInfo | MangaInfo)]; - } - } - - return media; - } catch (e) { - console.log(colors.red(`Error while filling media info for ${media.id} with provider ${provider.id}`)); - console.error(e); - return media; - } -} - -export interface MappedResult { - id: string; - malId: string; - slug: string; - data: Result; - similarity: number; -} diff --git a/anify-backend/src/lib/search.ts b/anify-backend/src/lib/search.ts deleted file mode 100644 index 935e3a7..0000000 --- a/anify-backend/src/lib/search.ts +++ /dev/null @@ -1,19 +0,0 @@ -import Database from "../database"; -import emitter, { Events } from "../helper/event"; -import { Format, Type } from "../mapping"; -import AniList from "../mapping/impl/information/anilist"; - -export const loadSearch = async (data: { query: string; type: Type; formats: Format[] }) => { - // First check if exists in database - const existing = await Database.search(data.query, data.type, data.formats, 1, 15); - if (existing.length > 0) { - await emitter.emitAsync(Events.COMPLETED_SEARCH_LOAD, existing); - return existing; - } - - const result = await new AniList().search(data.query, data.type, data.formats, 0, 10); - - await emitter.emitAsync(Events.COMPLETED_SEARCH_LOAD, result); - - return result; -}; diff --git a/anify-backend/src/lib/season.ts b/anify-backend/src/lib/season.ts deleted file mode 100644 index 91c29fd..0000000 --- a/anify-backend/src/lib/season.ts +++ /dev/null @@ -1,11 +0,0 @@ -import emitter, { Events } from "../helper/event"; -import { Format, Type } from "../mapping"; -import AniList from "../mapping/impl/information/anilist"; - -export const loadSeasonal = async (data: { type: Type; formats: Format[] }) => { - const result = await new AniList().fetchSeasonal(data.type, data.formats); - - await emitter.emitAsync(Events.COMPLETED_SEASONAL_LOAD, result); - - return result; -}; diff --git a/anify-backend/src/lib/skipTimes.ts b/anify-backend/src/lib/skipTimes.ts deleted file mode 100644 index 97a83d9..0000000 --- a/anify-backend/src/lib/skipTimes.ts +++ /dev/null @@ -1,146 +0,0 @@ -import emitter, { Events } from "../helper/event"; -import { Episode, Source } from "../mapping/impl/anime"; -import AniList from "../mapping/impl/information/anilist"; -import colors from "colors"; -import Database from "../database"; - -export const loadSkipTimes = async (data: { id: string; episode: number; toInsert?: Source }): Promise<{ number: number; intro: { start: number; end: number }; outro: { start: number; end: number } } | null> => { - const existing = await Database.findSkipTimes(data.id); - - if (existing) { - for (let i = 0; i < existing.episodes.length; i++) { - if (existing.episodes[i].number === data.episode) { - await emitter.emitAsync(Events.COMPLETED_SKIPTIMES_LOAD, existing.episodes[i]); - return existing.episodes[i]; - } - } - } - - if (!data.toInsert) { - await emitter.emitAsync(Events.COMPLETED_SKIPTIMES_LOAD, null); - return null; - } - - let toInsert; - if (!existing) { - toInsert = { - id: data.id, - episodes: [], - }; - } else { - toInsert = existing; - } - if (data.toInsert.intro.end > 0 || data.toInsert.outro.end > 0) { - toInsert.episodes.push({ - intro: data.toInsert.intro, - outro: data.toInsert.outro, - number: data.episode, - }); - } - - await Database.updateSkipTimes(data.id, toInsert.episodes); - - // temp - console.log(colors.green(`Inserted skip times for ${data.id} episode ${data.episode}`)); - - const skipTimes = toInsert.episodes.find((e: Episode) => e.number === data.episode); - if (!skipTimes) { - await emitter.emitAsync(Events.COMPLETED_SKIPTIMES_LOAD, null); - return null; - } - - await emitter.emitAsync(Events.COMPLETED_SKIPTIMES_LOAD, skipTimes); - return skipTimes; -}; - -export async function insertAllSkipTimes() { - const aniList = new AniList(); - const data = await (await fetch(`https://raw.githubusercontent.com/Eltik/episodescrape/master/data/compiled/aniskip.json`)).json(); - for (let i = 0; i < Object.entries(data).length; i++) { - const malId = Object.entries(data)[i][0]; - - const query = `query ($id: Int) { - Media (id: $id) { - id - title { - romaji - english - native - userPreferred - } - } - }`; - const variables = { - id: parseInt(malId), - }; - - const req = await aniList.request("https://graphql.anilist.co", { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - body: JSON.stringify({ - query, - variables, - }), - }); - const media = (await req.json()).data.Media; - - const existing = await Database.findSkipTimes(media.id); - - if (existing) continue; - - const episodes: { duration: string; number: number; intro?: number[]; outro?: number[] }[] = Object.entries(data)[i][1] as any; - const result: { duration: string; number: number; intro: { start: number; end: number }; outro: { start: number; end: number } }[] = []; - - for (let j = 0; j < episodes.length; j++) { - if (episodes[j].intro && episodes[j].outro) { - result.push({ - duration: episodes[j].duration, - number: episodes[j].number, - intro: { - start: episodes[j].intro?.[0] ?? 0, - end: episodes[j].intro?.[1] ?? 0, - }, - outro: { - start: episodes[j].outro?.[0] ?? 0, - end: episodes[j].outro?.[1] ?? 0, - }, - }); - } else if (episodes[j].intro) { - result.push({ - duration: episodes[j].duration, - number: episodes[j].number, - intro: { - start: episodes[j].intro?.[0] ?? 0, - end: episodes[j].intro?.[1] ?? 0, - }, - outro: { - start: 0, - end: 0, - }, - }); - } else if (episodes[j].outro) { - result.push({ - duration: episodes[j].duration, - number: episodes[j].number, - intro: { - start: 0, - end: 0, - }, - outro: { - start: episodes[j].intro?.[0] ?? 0, - end: episodes[j].intro?.[1] ?? 0, - }, - }); - } - } - - await Database.updateSkipTimes(media.id, result); - - console.log(`Inserted skip times for ${media.title.romaji} (${media.id})`); - } - - return "Done"; -} diff --git a/anify-backend/src/lib/upload.ts b/anify-backend/src/lib/upload.ts deleted file mode 100644 index 5833435..0000000 --- a/anify-backend/src/lib/upload.ts +++ /dev/null @@ -1,312 +0,0 @@ -import { join } from "path"; -import emitter, { Events } from "../helper/event"; -import { Chapter, Page } from "../mapping/impl/manga"; -import { createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, unlinkSync } from "fs"; -import colors from "colors"; -import { wait } from "../helper"; -import { Readable } from "stream"; -import { finished } from "stream/promises"; -import PDFDocument from "pdfkit"; -import probe from "probe-image-size"; -import FormData from "form-data"; -import Database from "../database"; -import { Manga, Type } from "../mapping"; -import { env } from "../env"; -import { readFile, unlink } from "fs/promises"; - -export const uploadPages = async (data: { id: string; providerId: string; chapter: Chapter; readId: string; pages: Page[] }) => { - const useMixdrop = env.USE_MIXDROP; - if (useMixdrop) { - const manga = await Database.info(data.id); - if (!manga) return await emitter.emitAsync(Events.COMPLETED_PAGE_UPLOAD, ""); - - const chapters = (manga as Manga).chapters; - const mixdrop = chapters.data.find((x) => x.providerId === data.providerId)?.chapters.find((x) => x.id === data.chapter.id)?.mixdrop; - - const mixdropEmail = env.MIXDROP_EMAIL; - const mixdropKey = env.MIXDROP_KEY; - - // Check if the file is removed - const isRemoved = await checkIsDeleted(mixdropEmail ?? "", mixdropKey ?? "", mixdrop ?? ""); - if (!isRemoved && mixdrop != undefined) return mixdrop; - - const result: string[] = []; - - for (const page of data.pages) { - //const res: UploadStatus = await (await fetch(`https://api.mixdrop.co/remoteupload?email=${mixdropEmail}&key=${mixdropKey}&url=${page.url}&folder=${encodeURIComponent(`manga/${data.id}/${data.providerId}/${data.chapter.title}`)}&name=${page.index}`)).json(); - //result.push(res.result.filterRef); - } - - const pdfPath = await createPDF(data.id, data.providerId, data.chapter, data.pages); - await readFile(pdfPath); - - // Upload PDF - const form = new FormData(); - form.append("email", mixdropEmail); - form.append("key", mixdropKey); - form.append("file", createReadStream(pdfPath), `${data.chapter.title.replace(/[^\w .-]/gi, "")}.pdf`); - form.append("folder", `manga/${data.id}/${data.providerId}/${data.chapter.title.replace(/[^\w .-]/gi, "")}`); - - return new Promise((resolve, reject) => { - form.submit("https://ul.mixdrop.co/api", async (err, res) => { - if (err) { - console.log(err); - return; - } - - res.on("data", (chunk) => { - try { - const res = JSON.parse(chunk.toString()); - if (res.success) result.push(res.result.fileref); - } catch (e) { - console.log(e); - } - }); - - res.on("end", async () => { - // Insert into database - for (const chap of chapters.data) { - if (chap.providerId === data.providerId) { - const chaps = chap.chapters; - for (const ch of chaps) { - if (ch.id === data.chapter.id) { - ch.mixdrop = result[0]; - } - } - } - } - - await Database.update(data.id, Type.MANGA, { - chapters, - }); - - const maxThreshold = 100; - let threshold = 0; - - const interval = setInterval(async () => { - const isComplete = await checkRemoteStatus(result[0]); - const key = Object.keys(isComplete.result)[0]; - - if (isComplete.result[key].status === "OK") { - console.log(colors.green("Completed uploading ") + colors.blue(data.chapter.title) + colors.green(" to Mixdrop")); - - // Cleanup - try { - await unlink(pdfPath); - - const parentFolder = join(__dirname, `./manga/${data.id}/${data.providerId}/${data.chapter.title.replace(/[^\w .-]/gi, "")}`); - if (existsSync(parentFolder)) { - const files = readdirSync(parentFolder); - if (files.length === 0) { - await unlink(parentFolder); - - const providerFolder = join(__dirname, `./manga/${data.id}/${data.providerId}`); - if (existsSync(providerFolder)) { - const files = readdirSync(providerFolder); - if (files.length === 0) { - await unlink(providerFolder); - - const mangaFolder = join(__dirname, `./manga/${data.id}`); - if (existsSync(mangaFolder)) { - const files = readdirSync(mangaFolder); - if (files.length === 0) { - await unlink(mangaFolder); - } - } - } - } - } - } - } catch (e) { - //console.error(colors.red("Error during file/folder cleanup:"), e); - } - - resolve(result[0]); - clearInterval(interval); - return; - } else { - if (threshold >= maxThreshold + 5) { - console.error(colors.red("ERROR: ") + colors.blue(`Mixdrop upload for ${data.chapter.title} is taking too long.`)); - await unlink(pdfPath); - clearInterval(interval); - reject(); - return; - } - threshold++; - } - }, 1000); - - await emitter.emitAsync(Events.COMPLETED_PAGE_UPLOAD, result[0]); - }); - }); - }); - } else { - return await emitter.emitAsync(Events.COMPLETED_PAGE_UPLOAD, ""); - } -}; - -const checkRemoteStatus = async (mixdrop: string): Promise => { - const mixdropEmail = env.MIXDROP_EMAIL; - const mixdropKey = env.MIXDROP_KEY; - - const res: UploadStatus = await (await fetch(`https://api.mixdrop.co/fileinfo2?email=${mixdropEmail}&key=${mixdropKey}&ref[]=${mixdrop}`)).json(); - return res; -}; - -export const createPDF = async (id: string, providerId: string, chapter: Chapter, pages: Page[]): Promise => { - const parentFolder = join(__dirname, `./manga/${id}/${providerId}/${chapter.title.replace(/[^\w .-]/gi, "")}`); - if (existsSync(`${parentFolder}/${chapter.title.replace(/[^\w .-]/gi, "")}.pdf`)) return `${parentFolder}/${chapter.title.replace(/[^\w .-]/gi, "")}.pdf`; - - if (!existsSync(parentFolder)) { - mkdirSync(parentFolder, { recursive: true }); - } - - console.log(colors.blue("Creating PDF for ") + colors.green(chapter.title)); - - const promises: any[] = []; - for (let i = 0; i < pages.length; i++) { - const request = new Promise(async (resolve, reject) => { - const link = pages[i].url; - const page = pages[i].index; - - const pagePath = join(parentFolder, `/${page}.png`); - - if (link) { - if (!existsSync(pagePath)) { - await wait(50); - await downloadFile(link, pagePath, { - ...pages[i].headers, - Connection: "keep-alive", - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36", - "Accept-Language": "en-US,en;q=0.9", - "Accept-Encoding": "gzip, deflate, br", - Accept: "*/*", - }); - resolve(true); - } else { - resolve(true); - } - } - }); - - promises.push(request); - } - - await Promise.all(promises); - - const doc = new PDFDocument({ - autoFirstPage: false, - }); - const pdfStream = createWriteStream(`${parentFolder}/${chapter.title.replace(/[^\w .-]/gi, "")}.pdf`); - doc.pipe(pdfStream); - - const images = readdirSync(parentFolder).filter((file) => file.endsWith(".png")); - - const files: (string | number)[][] = []; - for (let i = 0; i < images.length; i++) { - const file = images[i]; - const a: string | number = file.split(".")[0]; - files.push([file, a ? a.toString() : ""]); - } - files.sort((a, b) => parseFloat(a[1].toString()) - parseFloat(b[1].toString())); - - for (let i = 0; i < files.length; i++) { - const file = files[i][0]; - const result = await probe(createReadStream(join(parentFolder, "/" + file))); - let width = result.width; - let height = result.height; - const ratio = (width + height) / 2; - const a7Ratio = 338.266666661706; - const scale = a7Ratio / ratio; - - width = width * scale; - height = height * scale; - - try { - doc.addPage({ size: [width, height] }).image(join(parentFolder, "/" + file), 0, 0, { align: "center", valign: "center", width: width, height: height }); - } catch (e) { - console.log(colors.red("Unable to add page ") + colors.blue(file + "") + colors.red(" to PDF ") + colors.blue(id)); - } - } - doc.end(); - - // Remove all images - for (let i = 0; i < images.length; i++) { - const file = images[i]; - const path = join(parentFolder, "/" + file); - if (existsSync(path)) { - try { - unlinkSync(path); - } catch (e) { - console.log(colors.red("Unable to delete file ") + colors.blue(file + "") + colors.red(" from ") + colors.blue(id)); - } - } - } - - return `${parentFolder}/${chapter.title.replace(/[^\w .-]/gi, "")}.pdf`; -}; - -export const checkIsDeleted = async (email: string, key: string, fileRef: string) => { - let pages = 1; - const initial = await (await fetch(`https://api.mixdrop.co/removed?email=${email}&key=${key}&page=1`)).json(); - if (!Array.isArray(initial.result)) return false; - - for (const file of initial.result) { - if (file.fileref === fileRef) return true; - } - - pages = initial.pages; - - for (let i = 2; i <= pages; i++) { - const initial = await (await fetch(`https://api.mixdrop.co/removed?email=${email}&key=${key}&page=${i}`)).json(); - for (const file of initial.result) { - if (file.fileref === fileRef) return true; - } - } - - return false; -}; - -async function downloadFile(file: string, path: string, headers?: any) { - if (existsSync(path)) return; - - const response = await fetch(file, { - headers: headers, - }); - - if (!response.ok) { - throw new Error(`Request failed with status: ${response.status} ${response.statusText}`); - } - - const fileStream = createWriteStream(path, { flags: "wx" }); - await finished(Readable.fromWeb(response.body as any).pipe(fileStream)); -} - -interface UploadStatus { - success: true; - result: ResultData; -} - -type ResultData = { - [key: string]: FileData; -}; - -type FileData = { - fileref: string; - title: string; - size: string; - duration: null; - subtitle: boolean; - isvideo: boolean; - isaudio: boolean; - added: string; - status: string; - deleted: boolean; - thumb: null; - url: string; - yourfile: boolean; -}; - -declare module "stream" { - function fromWeb(input: any): Readable; -} diff --git a/anify-backend/src/mapping/impl/anime/animeflix.ts b/anify-backend/src/mapping/impl/anime/animeflix.ts deleted file mode 100644 index 85785d4..0000000 --- a/anify-backend/src/mapping/impl/anime/animeflix.ts +++ /dev/null @@ -1,150 +0,0 @@ -import AnimeProvider, { Episode, Source, StreamingServers, SubType } from "."; -import { Format, Result } from "../.."; -import Extractor from "../../../helper/extractor"; - -export default class AnimeFlix extends AnimeProvider { - override rateLimit = 250; - override id = "animeflix"; - override url = "https://animeflix.live"; - - private api = "https://api.animeflix.live"; - private userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.111 Safari/537.36"; - - override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; - - override get subTypes(): SubType[] { - return [SubType.SUB, SubType.DUB]; - } - - override get headers(): Record | undefined { - return { - Referer: this.api, - }; - } - - override async search(query: string, format?: Format, year?: number): Promise { - const request = await this.request( - `${this.api}/info?query=${encodeURIComponent(query)}&limit=20`, - { - headers: { - "User-Agent": this.userAgent, - }, - }, - true - ); - if (!request.ok) { - return []; - } - const data = await request.json(); - const results: Result[] = data.map((res: any) => ({ - id: res.slug, - title: res.title.userPreferred || res.title.english || res.title.romaji || res.title.native, - altTitles: [res.title.english, res.title.romaji, res.title.native, res.title.userPreferred].filter(Boolean), - format: res.type, - img: res.images.large || res.images.medium || res.images.small, - providerId: this.id, - year: res.startDate?.year || 0, - })); - - return results; - } - - override async fetchEpisodes(id: string): Promise { - // /getslug/fuufu-ijou-koibito-miman - // /idtoinfo?ids=[] - // /episodes?id=fuufu-ijou-koibito-miman&dub=false&a=j43o4d4d3o4d1j4142474d1j4347413k414c471j4541453j46 - - const hash = this.generateHash(id); - - const [dataResponse, dubResponse] = await Promise.all([ - this.request( - `${this.api}/episodes?id=${id}&dub=false&a=${hash}`, - { - headers: { - "User-Agent": this.userAgent, - }, - }, - true - ), - this.request( - `${this.api}/episodes?id=${id}&dub=true&a=${hash}`, - { - headers: { - "User-Agent": this.userAgent, - }, - }, - true - ), - ]); - - if (!dataResponse.ok || !dubResponse.ok) { - return []; - } - - const [data, dubData] = await Promise.all([dataResponse.json(), dubResponse.json()]); - - const dubNumbers = new Set((dubData?.episodes ?? []).map((dub: any) => dub.number)); - - const results: Episode[] = data.episodes.map((res: any) => ({ - id: `/watch/${id}-episode-${res.number}?server=`, - img: res.image ?? null, - isFiller: false, - number: res.number, - title: res.title ?? "Episode " + res.number, - hasDub: res.dub ?? dubNumbers.has(res.number), - })); - - return results; - } - - override async fetchSources(id: string, subType: SubType | undefined, server: StreamingServers = StreamingServers.AnimeFlix): Promise { - const splitId = id.split("-episode-"); - const episodeNumber = splitId[1].split("?")[0]; - const watchId = splitId[0].split("/watch/")[1]; - - if (subType === SubType.DUB) { - id = `/watch/${watchId}-dub-episode-${episodeNumber}?server=`; - } - - const headers = { - "User-Agent": this.userAgent, - }; - - const response = await this.request(`${this.api}${id}`, { headers }, true); - const data = await response.json(); - - const result: Source = { - sources: [], - subtitles: [], - audio: [], - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - headers: this.headers ?? {}, - }; - - if (!data.source) return result; - - return await new Extractor(data.source, result).extract(server); - } - - private generateHash(source: string): string { - const currentDate = new Date(); - const averageMonthAndDate = 9 + (currentDate.getUTCDate() + currentDate.getUTCMonth()) / 2; - let result = "j4"; - - const inputLength = source.length; - for (let i = 0; i < inputLength; i++) { - const charCode = source.charCodeAt(i); - const encodedValue = charCode.toString(Math.floor(averageMonthAndDate)); - result += encodedValue; - } - - return result; - } -} diff --git a/anify-backend/src/mapping/impl/anime/animepahe.ts b/anify-backend/src/mapping/impl/anime/animepahe.ts deleted file mode 100644 index 5175e2a..0000000 --- a/anify-backend/src/mapping/impl/anime/animepahe.ts +++ /dev/null @@ -1,170 +0,0 @@ -import AnimeProvider, { Episode, Source, StreamingServers, SubType } from "."; -import { Format, Formats, Result } from "../.."; -import { load } from "cheerio"; -import Extractor from "../../../helper/extractor"; - -export default class AnimePahe extends AnimeProvider { - override rateLimit = 250; - override id = "animepahe"; - override url = "https://animepahe.com"; - - override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; - - override get subTypes(): SubType[] { - return [SubType.SUB]; - } - - override get headers(): Record | undefined { - return { Referer: "https://kwik.cx" }; - } - - override async search(query: string, format?: Format, year?: number): Promise { - const request = await this.request(`${this.url}/api?m=search&q=${encodeURIComponent(query)}`); - if (!request.ok) { - return []; - } - const data = await request.json(); - const results: Result[] = []; - - if (!data?.data) { - return []; - } - - data.data.map((item: { id: number; title: string; year: number; poster: string; type: string; session: string }) => { - const formatString: string = item.type.toUpperCase(); - const f: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; - - results.push({ - id: String(item.id) ?? item.session, - title: item.title, - year: item.year, - img: item.poster, - format: f, - altTitles: [], - providerId: this.id, - }); - }); - - return results; - } - - override async fetchEpisodes(id: string): Promise { - const episodes: Episode[] = []; - - const req = await (await this.request(`${this.url}${id.includes("-") ? `/anime/${id}` : `/a/${id}`}`)).text(); - - const $ = load(req); - - const tempId = $("head > meta[property='og:url']").attr("content")!.split("/").pop()!; - const { last_page, data } = await (await this.request(`${this.url}/api?m=release&id=${tempId}&sort=episode_asc&page=1`)).json(); - - data.map((item: { id: number; episode: number; title: string; snapshot: string; filler: number; created_at?: string }) => { - const updatedAt = new Date(item.created_at ?? Date.now()).getTime(); - - episodes.push({ - id: item.id + "-" + id, - number: item.episode, - title: item.title && item.title.length > 0 ? item.title : "Episode " + item.episode, - img: item.snapshot, - isFiller: item.filler === 1, - hasDub: false, - updatedAt, - }); - }); - - const pageNumbers = Array.from({ length: last_page - 1 }, (_, i) => i + 2); - - const promises = pageNumbers.map((pageNumber) => this.request(`${this.url}/api?m=release&id=${tempId}&sort=episode_asc&page=${pageNumber}`).then((res) => res.json())); - const results = await Promise.all(promises); - - results.forEach((showData) => { - for (const data of showData.data) { - if (data) { - const updatedAt = new Date(data.created_at ?? Date.now()).getTime(); - - episodes.push({ - id: data.id + "-" + id, - number: data.episode, - title: data.title && data.title.length > 0 ? data.title : "Episode " + data.episode, - img: data.snapshot, - isFiller: data.filler === 1, - hasDub: false, - updatedAt, - }); - } - } - }); - (data as any[]).sort((a, b) => a.number - b.number); - return episodes; - } - - override async fetchSources(id: string, subType: SubType = SubType.SUB, server: StreamingServers = StreamingServers.Kwik): Promise { - const animeId = id.split("-").pop()!; - const episodeId = id.split("-")[0]; - - const req = await this.request(`${this.url}${animeId.includes("-") ? `/anime/${animeId}` : `/a/${animeId}`}`); - - try { - const url = req.url; - // Need session id to fetch the watch page - const sessionId = url.split("/anime/").pop()!; - - const $ = load(await req.text()); - const tempId = $("head > meta[property='og:url']").attr("content")!.split("/").pop()!; - const { last_page, data } = await (await this.request(`${this.url}/api?m=release&id=${tempId}&sort=episode_asc&page=1`)).json(); - - let episodeSession = ""; - - for (let i = 0; i < data.length; i++) { - if (String(data[i].id) === episodeId) { - episodeSession = data[i].session; - break; - } - } - - if (episodeSession === "") { - for (let i = 1; i < last_page; i++) { - const data = await (await this.request(`${this.url}/api?m=release&id=${tempId}&sort=episode_asc&page=${i + 1}`)).json(); - - for (let j = 0; j < data.length; j++) { - if (String(data[j].id) === episodeId) { - episodeSession = data[j].session; - break; - } - } - - if (episodeSession !== "") break; - } - } - - if (episodeSession === "") return undefined; - - const watchReq = await (await this.request(`${this.url}/play/${sessionId}/${episodeSession}`)).text(); - - const regex = /https:\/\/kwik\.cx\/e\/\w+/g; - const matches = watchReq.match(regex); - - if (matches === null) return undefined; - - const result: Source = { - sources: [], - subtitles: [], - audio: [], - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - headers: this.headers ?? {}, - }; - - return await new Extractor(matches[0], result).extract(server); - } catch (e) { - console.error(e); - return undefined; - } - } -} diff --git a/anify-backend/src/mapping/impl/anime/gogoanime.ts b/anify-backend/src/mapping/impl/anime/gogoanime.ts deleted file mode 100644 index 4592c42..0000000 --- a/anify-backend/src/mapping/impl/anime/gogoanime.ts +++ /dev/null @@ -1,130 +0,0 @@ -import AnimeProvider, { Episode, Source, StreamingServers, SubType } from "."; -import { Format, Result } from "../.."; -import { load } from "cheerio"; -import Extractor from "../../../helper/extractor"; - -export default class GogoAnime extends AnimeProvider { - override rateLimit = 250; - override id = "gogoanime"; - override url = "https://gogoanimehd.to"; - - override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; - - override get subTypes(): SubType[] { - return [SubType.SUB, SubType.DUB]; - } - - override get headers(): Record | undefined { - return undefined; - } - - override async search(query: string, format?: Format, year?: number): Promise { - const request = await this.request(`${this.url}/search.html?keyword=${encodeURIComponent(query)}`); - if (!request.ok) { - return []; - } - const data = await request.text(); - const results: Result[] = []; - - const $ = load(data); - - $("ul.items > li").map((i, el) => { - const title = $("p.name a", el).text().trim(); - const id = $(el).find("div.img a").attr("href")!; - const releasedText = $("p.released", el).text().trim(); - const yearMatch = releasedText.match(/Released:\s+(\d{4})/); - const year = yearMatch ? parseInt(yearMatch[1]) : 0; - const img = $(el).find("div.img a img").attr("src")!; - - const format: Format = Format.UNKNOWN; - - results.push({ - id: id, - title: title, - altTitles: [], - img: img, - format, - year: year, - providerId: this.id, - }); - }); - - return results; - } - - override async fetchEpisodes(id: string): Promise { - const episodes: Episode[] = []; - - const data = await (await this.request(`${this.url}${id}`)).text(); - - const $ = load(data); - - const epStart = $("#episode_page > li").first().find("a").attr("ep_start"); - const epEnd = $("#episode_page > li").last().find("a").attr("ep_end"); - const movieId = $("#movie_id").attr("value"); - const alias = $("#alias_anime").attr("value"); - - const req = await (await this.request(`https://ajax.gogo-load.com/ajax/load-list-episode?ep_start=${epStart}&ep_end=${epEnd}&id=${movieId}&default_ep=${0}&alias=${alias}`)).text(); - - const $$ = load(req); - - $$("#episode_related > li").each((i, el) => { - episodes?.push({ - id: $(el).find("a").attr("href")?.trim()!, - number: parseFloat($(el).find(`div.name`).text().replace("EP ", "")), - title: $(el).find(`div.name`).text(), - isFiller: false, - img: null, - hasDub: id.includes("-dub"), - }); - }); - return episodes; - } - - override async fetchSources(id: string, subType = SubType.SUB, server: StreamingServers = StreamingServers.GogoCDN): Promise { - const result: Source = { - sources: [], - subtitles: [], - audio: [], - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - headers: this.headers ?? {}, - }; - - if (id.startsWith("http")) { - const serverURL = id; - const download = `https://gogohd.net/download${new URL(serverURL).search}`; - - return await new Extractor(serverURL, result).extract(server); - } - - const data = await (await this.request(`${this.url}${id}`)).text(); - - const $ = load(data); - - let serverURL: string; - - switch (server) { - case StreamingServers.GogoCDN: - serverURL = `${$("#load_anime > div > div > iframe").attr("src")}`; - break; - case StreamingServers.VidStreaming: - serverURL = `${$("div.anime_video_body > div.anime_muti_link > ul > li.vidcdn > a").attr("data-video")}`; - break; - case StreamingServers.StreamSB: - serverURL = $("div.anime_video_body > div.anime_muti_link > ul > li.streamsb > a").attr("data-video")!; - break; - default: - serverURL = `${$("#load_anime > div > div > iframe").attr("src")}`; - break; - } - - return await this.fetchSources(serverURL, subType, server); - } -} diff --git a/anify-backend/src/mapping/impl/anime/index.ts b/anify-backend/src/mapping/impl/anime/index.ts deleted file mode 100644 index 266ee29..0000000 --- a/anify-backend/src/mapping/impl/anime/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Format, ProviderType, type Result } from "../.."; -import Http from "../request"; - -export default abstract class AnimeProvider { - abstract rateLimit: number; - abstract id: string; - abstract url: string; - abstract formats: Format[]; - - public providerType: ProviderType = ProviderType.ANIME; - public customProxy: string | undefined; - - async search(query: string, format?: Format, year?: number): Promise { - return undefined; - } - - async fetchEpisodes(id: string): Promise { - return undefined; - } - - async fetchSources(id: string, subType: SubType = SubType.SUB, server: StreamingServers): Promise { - return undefined; - } - - async fetchServers(id: string): Promise { - return undefined; - } - - async request(url: string, config: RequestInit = {}, proxyRequest = false): Promise { - return Http.request(url, config, proxyRequest, 0, this.customProxy); - } - - abstract get subTypes(): SubType[]; - abstract get headers(): Record | undefined; -} - -export const enum SubType { - DUB = "dub", - SUB = "sub", -} - -export const enum StreamingServers { - AsianLoad = "asianload", - GogoCDN = "gogocdn", - StreamSB = "streamsb", - MixDrop = "mixdrop", - UpCloud = "upcloud", - VidCloud = "vidcloud", - StreamTape = "streamtape", - VizCloud = "vizcloud", - MyCloud = "mycloud", - Filemoon = "filemoon", - VidStreaming = "vidstreaming", - AllAnime = "allanime", - FPlayer = "fplayer", - Kwik = "kwik", - DuckStream = "duckstream", - DuckStreamV2 = "duckstreamv2", - BirdStream = "birdstream", - AnimeFlix = "animeflix", -} - -export type Episode = { - id: string; - title: string; - number: number; - isFiller: boolean; - img: string | null; - hasDub: boolean; - updatedAt?: number; -}; - -export type Source = { - sources: { url: string; quality: string }[]; - subtitles: { url: string; lang: string; label: string }[]; - audio: { url: string; name: string; language: string }[]; - intro: { - start: number; - end: number; - }; - outro: { - start: number; - end: number; - }; - headers: Record; -}; - -export type Server = { - name: string; - url: string; - type?: SubType; -}; diff --git a/anify-backend/src/mapping/impl/anime/kass.ts b/anify-backend/src/mapping/impl/anime/kass.ts deleted file mode 100644 index 10fd5d8..0000000 --- a/anify-backend/src/mapping/impl/anime/kass.ts +++ /dev/null @@ -1,320 +0,0 @@ -import AnimeProvider, { Episode, Server, Source, StreamingServers, SubType } from "."; -import { Format, Formats, Result } from "../.."; -import Extractor from "../../../helper/extractor"; - -export default class Kass extends AnimeProvider { - override rateLimit = 250; - override id = "kass"; - override url = "https://kickassanime.am"; - - override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; - - override get subTypes(): SubType[] { - return [SubType.SUB, SubType.DUB]; - } - - override get headers(): Record | undefined { - return { Origin: "https://vidnethub.net" }; - } - - override async search(query: string, format?: Format, year?: number): Promise { - const request = await this.request( - `${this.url}/api/search`, - { - method: "POST", - body: JSON.stringify({ - query, - }), - headers: { - "Content-type": "application/json", - Referer: `${this.url}/`, - Origin: this.url, - }, - }, - true - ); - - if (!request.ok) { - return []; - } - const data: SearchData[] = await request.json(); - - const results: Result[] = []; - - data.forEach((item) => { - results.push({ - id: item.slug, - altTitles: item.title_en ? [item.title_en, item.title] : [item.title], - title: item.title_en ?? item.title, - format: Formats.includes(item.type as Format) ? (item.type as Format) : Format.UNKNOWN, - img: `${this.url}/image/poster/${item.poster.hq ?? item.poster.sm}.${item.poster.formats.includes("webp") ? "webp" : item.poster.formats[0]}`, - year: item.year, - providerId: this.id, - }); - }); - - return results; - } - - override async fetchEpisodes(id: string): Promise { - const episodeJSONs: { sub?: Episodes; dub?: Episodes } = { dub: undefined, sub: undefined }; - - try { - episodeJSONs.sub = await (await this.request(`${this.url}/api/show/${id}/episodes?lang=ja-JP`, {}, true)).json(); - - try { - const promises: Promise[] = []; - - for (let i = 0; i < (episodeJSONs["sub"]?.pages ?? []).length; i++) { - if (i == 0) { - continue; - } - - promises.push(this.request(`${this.url}/api/show/${id}/episodes?lang=ja-JP&page=${episodeJSONs["sub"]?.pages[i].number}`, {}, true)); - } - - const results = await Promise.all(promises); - - for (const result of results) { - try { - const data = await result.json(); - episodeJSONs["sub"]?.result.push(...data.result); - } catch (err) { - console.warn(err); - } - } - } catch (err) { - console.warn(err); - } - } catch (err) { - episodeJSONs.dub = await (await this.request(`${this.url}/api/show/${id}/episodes?lang=en-US`, {}, true)).json(); - - try { - const promises: Promise[] = []; - - for (let i = 0; i < (episodeJSONs["dub"]?.pages ?? []).length; i++) { - if (i == 0) { - continue; - } - - promises.push(this.request(`${this.url}/api/show/${id}/episodes?lang=en-US&page=${episodeJSONs["dub"]?.pages[i].number}`, {}, true)); - } - - const results = await Promise.all(promises); - - for (const result of results) { - try { - const data = await result.json(); - episodeJSONs["dub"]?.result.push(...data.result); - } catch (err) { - console.warn(err); - } - } - } catch (err) { - console.warn(err); - } - } - - if (!episodeJSONs.dub) { - episodeJSONs.dub = await (await this.request(`${this.url}/api/show/${id}/episodes?lang=en-US`, {}, true)).json(); - - try { - const promises: Promise[] = []; - - for (let i = 0; i < (episodeJSONs["dub"]?.pages ?? []).length; i++) { - if (i == 0) { - continue; - } - - promises.push(this.request(`${this.url}/api/show/${id}/episodes?lang=en-US&page=${episodeJSONs["dub"]?.pages[i].number}`, {}, true)); - } - - const results = await Promise.all(promises); - - for (const result of results) { - try { - const data = await result.json(); - episodeJSONs["dub"]?.result.push(...data.result); - } catch (err) { - console.warn(err); - } - } - } catch (err) { - console.warn(err); - } - } - - if (episodeJSONs.sub?.pages?.length === 0) { - episodeJSONs.sub = undefined; - } - - if (episodeJSONs.dub?.pages?.length === 0) { - episodeJSONs.dub = undefined; - } - - const episodeJSON = episodeJSONs.sub ?? episodeJSONs.dub; - const dubData: { [episodeNumber: number]: { episode_string: string; slug: string } } = {}; - - if (episodeJSONs.sub && episodeJSONs.dub) { - for (let i = 0; i < episodeJSONs.dub?.result?.length; i++) { - const el = episodeJSONs.dub.result[i]; - let epNum = el.episode_number; - - if (epNum == 0) { - epNum = 0.1; - } - - dubData[epNum] = el; - } - } - - const episodes: Episode[] = []; - - for (let i = 0; i < (episodeJSON?.result ?? []).length; i++) { - const el = episodeJSON?.result[i]; - const isSub = episodeJSON === episodeJSONs.sub; - - let epNum = el?.episode_number ?? -1; - - if (epNum == 0) { - epNum = 0.1; - } - - const sourceID: any = {}; - - sourceID[isSub ? "sub" : "dub"] = `ep-${el?.episode_string}-${el?.slug}`; - - if (dubData[epNum] && isSub) { - sourceID["dub"] = `ep-${dubData[epNum].episode_string}-${dubData[epNum].slug}`; - } - - episodes.push({ - id: encodeURIComponent( - JSON.stringify({ - id, - epNum, - sourceID: JSON.stringify(sourceID), - }) - ), - title: `${el?.title ? el.title : `Episode ${epNum}`}`, - number: epNum, - img: `${this.url}/image/thumbnail/${el?.thumbnail?.sm ?? el?.thumbnail?.sm}.${el?.thumbnail?.formats.includes("webp") ? "webp" : el?.thumbnail?.formats[0]}`, - hasDub: !!dubData[epNum], - isFiller: false, - }); - } - - return episodes; - } - - override async fetchSources(id: string, subType: SubType | undefined, server: StreamingServers = StreamingServers.BirdStream): Promise { - const source: Source = { - sources: [], - subtitles: [], - audio: [], - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - headers: this.headers ?? {}, - }; - - const servers = await this.fetchServers(id); - - let s = servers?.filter((s) => s.name === server.toString() && s.type === subType)[0]; - - if (!s) { - switch (server) { - case StreamingServers.DuckStream: - s = servers?.filter((s) => s.name === StreamingServers.BirdStream.toString() && s.type === subType)[0]; - server = StreamingServers.BirdStream; - break; - case StreamingServers.BirdStream: - s = servers?.filter((s) => s.name === StreamingServers.DuckStream.toString() && s.type === subType)[0]; - server = StreamingServers.DuckStream; - break; - case StreamingServers.DuckStreamV2: - s = servers?.filter((s) => s.name === StreamingServers.DuckStream.toString() && s.type === subType)[0]; - server = StreamingServers.DuckStream; - break; - default: - break; - } - - if (!s) { - s = servers?.filter((s) => s.name === StreamingServers.DuckStreamV2.toString() && s.type === subType)[0]; - server = StreamingServers.DuckStreamV2; - } - - if (!s) return undefined; - } - - return await new Extractor(s.url, source).extract(server); - } - - override async fetchServers(id: string): Promise { - const params = JSON.parse(decodeURIComponent(id)); - id = params.id; - - const links = JSON.parse(params.sourceID); - - const server: Server[] = []; - - for (const type in links) { - const slug = links[type]; - const videoJSON = await (await this.request(`${this.url}/api/show/${id}/episode/${slug}`, {}, true)).json(); - const servers = videoJSON.servers; - - for (const s of servers) { - if (s.name?.toLowerCase() === "vidstreaming") s.name = StreamingServers.DuckStreamV2.toString(); - - server.push({ - name: s.name?.toLowerCase(), - url: s.src, - type: type === "sub" ? SubType.SUB : SubType.DUB, - }); - } - } - - return server; - } -} - -interface SearchData { - rating: string; - slug: string; - start_date: string; - status: string; - title: string; - title_en: string; - type: string; - year: number; - poster: { - formats: string[]; - sm: string; - aspectRatio: number; - hq: string; - }; -} - -interface Episodes { - current_page: number; - pages: { number: number; from: string; to: string; eps: (string | number)[] }[]; - result: { - slug: string; - title?: string; - duration_ms?: number; - episode_number: number; - episode_string: string; - thumbnail?: { - formats: string[]; - sm: string; - aspectRatio: number; - hq: string; - }; - }[]; -} diff --git a/anify-backend/src/mapping/impl/anime/nineanime.ts b/anify-backend/src/mapping/impl/anime/nineanime.ts deleted file mode 100644 index ce19b09..0000000 --- a/anify-backend/src/mapping/impl/anime/nineanime.ts +++ /dev/null @@ -1,348 +0,0 @@ -import AnimeProvider, { Episode, Server, Source, StreamingServers, SubType } from "."; -import { load } from "cheerio"; - -import Extractor from "../../../helper/extractor"; -import { Format, Formats, type Result } from "../.."; -import { env } from "../../../env"; - -export default class NineAnime extends AnimeProvider { - override rateLimit = 250; - override id = "9anime"; - override url = "https://aniwave.to"; - override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; - - private resolver: string | undefined = env.NINEANIME_RESOLVER; - private resolverKey: string | undefined = env.NINEANIME_KEY || `9anime`; - - override get subTypes(): SubType[] { - return [SubType.SUB, SubType.DUB]; - } - - override get headers(): Record | undefined { - return { Referer: "https://vidstream.pro/", "X-Requested-With": "XMLHttpRequest" }; - } - - override async search(query: string, format?: Format, year?: number): Promise { - const vrf = await this.getSearchVRF(query); - const data = await (await this.request(`${this.url}/ajax/anime/search?keyword=${encodeURIComponent(query)}&${vrf.vrfQuery}=${encodeURIComponent(vrf.url)}`, {}, true)).json(); - - const $ = load(data.result.html); - - const results: Result[] = $("div.items > a.item") - .map((i, el) => { - const title = $(el).find("div.name"); - const altTitles: string[] = [title.attr("data-jp")!]; - - const year = parseInt($(el).find("div.info div.meta span.dot").last()?.text()?.trim()?.split(",")[1]) || 0; - - const formatString = $(el).find("div.info div.meta span.dot").eq(-2)?.text()?.trim(); - const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; - - return { - id: $(el).attr("href")!, - title: title.text().trim(), - altTitles, - year, - format, - img: $(el).find("img").attr("src")!, - providerId: this.id, - }; - }) - .get(); - - return results; - } - - override async fetchEpisodes(id: string): Promise { - const data = await (await this.request(`${this.url}${id}`, {})).text(); - - const $ = load(data); - - const nineId = $("#watch-main").attr("data-id")!; - - const vrf = await this.getVRF(nineId); - - const req = await this.request(`${this.url}/ajax/episode/list/${nineId}?${vrf.vrfQuery}=${encodeURIComponent(vrf.url)}`, {}, true); - - const $$ = load((await req.json()).result); - - const episodes: Episode[] = []; - - for (const el of $$("div.episodes > ul > li")) { - const liTitle = $(el).attr("title")?.split(" - ")?.[0]?.split("Release: ")[1] ?? new Date().toDateString(); - - const updatedAt = new Date(liTitle).getTime(); - - const episode: Episode = { - //id: ids[0], <- if i only want sub - id: $$(el).find("a").attr("data-ids")!, - number: parseInt($$(el).find("a").attr("data-num")?.toString()!), - title: $$(el).find("span").text()?.length > 0 ? $$(el).find("span").text() : "Episode " + $$(el).find("a").attr("data-num"), - isFiller: $$(el).find("a").hasClass("filler"), - img: null, - hasDub: $$(el).find("a").attr("data-dub")?.toString() === "1", - updatedAt, - }; - - episodes.push(episode); - } - - return episodes; - } - - override async fetchSources(id: string, subType: SubType = SubType.SUB, server: StreamingServers = StreamingServers.MyCloud): Promise { - const result: Source = { - sources: [], - subtitles: [], - audio: [], - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - headers: this.headers ?? {}, - }; - - if (id.startsWith("http")) { - const serverUrl = new URL(id); - - const req = await this.request(serverUrl.href, {}); - if (!req.ok) { - return result; - } - const json = await req.json(); - if (!json.result) { - return result; - } - - const serverID = serverUrl.href.split(`${this.url}/ajax/server/`)[1].split("?vrf")[0]; - const serverVrf = await this.getRawVRF(serverID); - - const serverSource = await (await this.request(`${this.url}/ajax/server/${serverID}?${serverVrf.vrfQuery}=${encodeURIComponent(serverVrf.url)}`, {}, true)).json(); - - try { - const skipData = JSON.parse((await this.decodeURL(json.result?.skip_data!)).url); - result.intro.start = skipData?.intro?.[0] ?? 0; - result.intro.end = skipData?.intro?.[1] ?? 0; - - result.outro.start = skipData?.outro?.[0] ?? 0; - result.outro.end = skipData?.outro?.[1] ?? 0; - } catch (e) { - console.error("9Anime skip data error"); - console.error(e); - } - - const source = (await (await this.request(`${this.resolver}/decrypt?query=${encodeURIComponent(serverSource.result?.url)}&apikey=${this.resolverKey}`)).json()).url.split("/").pop(); - - return await new Extractor(source, result).extract(server); - } - - if (subType === SubType.SUB) { - id = id.split(",")[0]; - } else { - id = id.split(",")[1]; - if (!id) return result; - } - - const servers = (await this.fetchServers(id))!; - - let s = servers.find((s) => s.name === server); - - switch (server) { - case StreamingServers.VizCloud: - s = servers.find((s) => s.name === "vidstream")!; - if (!s) throw new Error("Vidstream server found"); - break; - case StreamingServers.StreamTape: - s = servers.find((s) => s.name === "streamtape"); - if (!s) throw new Error("Streamtape server found"); - break; - case StreamingServers.MyCloud: - s = servers.find((s) => s.name === "mycloud"); - if (!s) throw new Error("Mycloud server found"); - break; - case StreamingServers.Filemoon: - s = servers.find((s) => s.name === "filemoon"); - if (!s) throw new Error("Filemoon server found"); - break; - default: - throw new Error("Server not found"); - } - - return await this.fetchSources(s.url, subType, server); - } - - override async fetchServers(id: string): Promise { - const vrf = await this.getVRF(id); - const url = `${this.url}/ajax/server/list/${id}?${vrf.vrfQuery}=${encodeURIComponent(vrf.url)}`; - - const data = await (await this.request(url, {}, true)).json(); - - const $ = load(data.result); - - const servers: Server[] = []; - const promises: Promise[] = []; - - $(".type > ul > li").each((i, el) => { - const promise: Promise = new Promise(async (resolve, reject) => { - const serverId = $(el).attr("data-link-id")!; - const vrf = await this.getRawVRF(serverId); - servers.push({ - name: $(el).text().toLocaleLowerCase(), - url: `${this.url}/ajax/server/${serverId}?${vrf.vrfQuery}=${encodeURIComponent(vrf.url)}`, - }); - resolve(true); - }); - promises.push(promise); - }); - - await Promise.all(promises); - return servers; - } - - private async getVRF(query: string): Promise { - if (!this.resolver) - return { - url: query, - vrfQuery: "vrf", - }; - - return await (await this.request(`${this.resolver}/vrf?query=${encodeURIComponent(query)}&apikey=${this.resolverKey}`, {})).json(); - } - - public async getSearchVRF(query: string): Promise { - if (!this.resolver) - return { - url: query, - vrfQuery: "vrf", - }; - - return await (await this.request(`${this.resolver}/9anime-search?query=${encodeURIComponent(query)}&apikey=${this.resolverKey}`, {})).json(); - } - - private async getRawVRF(query: string): Promise { - if (!this.resolver) - return { - url: query, - vrfQuery: "vrf", - }; - - return await (await this.request(`${this.resolver}/rawVrf?query=${encodeURIComponent(query)}&apikey=${this.resolverKey}`, {})).json(); - } - - private async decodeURL(query: string): Promise { - if (!this.resolver) - return { - url: query, - vrfQuery: "vrf", - }; - - return await (await this.request(`${this.resolver}/decrypt?query=${encodeURIComponent(query)}&apikey=${this.resolverKey}`, {})).json(); - } - - // This bypass works. However because it sends requests very quickly in a short amount of time, it causes proxies to get banned very quickly. - /* - override async request(url: string, options: RequestInit = {}, proxyRequest = true): Promise { - const proxy = proxyRequest ? ((this.customProxy?.length ?? 0) > 0 ? this.customProxy : Http.getRandomUnbannedProxy()) : undefined; - - const headers = { - "User-Agent": this.userAgent, - Referer: this.url, - }; - - const req1 = await Http.request(this.url, { headers }, proxyRequest, 0, proxy); - - const data1 = await req1.text(); - - if (!isString(data1)) { - return Http.request(url, options, proxyRequest, 0, proxy); - } - - // Extract _a and _b values - const _aMatch = data1.match(/var _a\s*=\s*'([0-9a-f]+)'/); - const _bMatch = data1.match(/_b\s*=\s*'([0-9a-f]+)'/); - const _a = _aMatch?.[1]; - const _b = _bMatch?.[1]; - if (!_a || !_b) { - return Http.request(url, options, proxyRequest, 0, proxy); - } - - // Now fetch k value - const req2 = await Http.request(`${this.url}/waf-js-run`, { headers }, proxyRequest, 0, proxy); - const data2 = await req2.text(); - - const context = { global: global, data: "" }; - vm.createContext(context); - - vm.runInContext( - ` - const location = { - href: "${this.url}/waf-js-run", - }; - - function EvalDecode(source) { - global._eval = global.eval; - - global.eval = (_code) => { - global.eval = global._eval; - return _code; - }; - - return global._eval(source); - } - - const code = EvalDecode("${data2}"); - data = code; - `, - context - ); - - const kMatch = context.data.match(/var k='([^']+)'/); - if (!kMatch) { - console.error("Failed to extract k value"); - return Http.request(url, options, proxyRequest, 0, proxy); - } - const k = kMatch[1]; - - // Construct o value - const l = k.length; - if (l !== _a.length || l !== _b.length) { - console.error("Length of k, _a and _b do not match"); - return Http.request(url, options, proxyRequest, 0, proxy); - } - const o = Array.from(k) - .map((char, i) => char + _a[i] + _b[i]) - .join(""); - - // Update URL with __jscheck parameter - const updatedUrl = this.url.replace(/&?__jscheck=[^&]+/g, "") + (this.url.indexOf("?") < 0 ? "?" : "&") + "__jscheck=" + o; - - const req3 = await Http.request(updatedUrl, { headers }, proxyRequest, 0, proxy); - const cookies = req3.headers["set-cookie"]; - - return Http.request(url, { headers: { Cookie: cookies?.join("; ") ?? "" }, ...options }, proxyRequest, 0, proxy); - } - */ - - /* - The waf page evals this: - (function (h) { - var k = 'c419b06b4c6579b50ff05adb3b8424f1', - l = k.length, - u = 'undefined', - i, o = ''; - if (typeof _a == u || typeof _b == u) return; - if (l != _a.length || l != _b.length) return; - for (i = 0; i < l; i++) o += k[i] + _a[i] + _b[i]; - location.href = h.replace(/&?__jscheck=[^&]+/g, '') + (h.indexOf('?') < 0 ? '?' : '&') + '__jscheck=' + o; - })(location.href); - */ -} - -type VRF = { - url: string; - vrfQuery: string; -}; \ No newline at end of file diff --git a/anify-backend/src/mapping/impl/anime/zoro.ts b/anify-backend/src/mapping/impl/anime/zoro.ts deleted file mode 100644 index 2e0bfb3..0000000 --- a/anify-backend/src/mapping/impl/anime/zoro.ts +++ /dev/null @@ -1,162 +0,0 @@ -import AnimeProvider, { Episode, Source, StreamingServers, SubType } from "."; -import { Format, Formats, Result } from "../.."; -import { load } from "cheerio"; -import Extractor from "../../../helper/extractor"; - -export default class Zoro extends AnimeProvider { - override rateLimit = 250; - override id = "zoro"; - //override url = "https://zoro.to"; - override url = "http://aniwatch.to"; - - override formats: Format[] = [Format.MOVIE, Format.ONA, Format.OVA, Format.SPECIAL, Format.TV, Format.TV_SHORT]; - - override get subTypes(): SubType[] { - return [SubType.SUB, SubType.DUB]; - } - - override get headers(): Record | undefined { - return undefined; - } - - override async search(query: string, format?: Format, year?: number): Promise { - const data = await (await this.request(`${this.url}/search?keyword=${encodeURIComponent(query)}`)).text(); - const results: Result[] = []; - - const $ = load(data); - - $(".film_list-wrap > div.flw-item").map((i, el) => { - const title = $(el).find("div.film-detail h3.film-name a.dynamic-name").attr("title")!.trim().replace(/\\n/g, ""); - const id = $(el).find("div:nth-child(1) > a").last().attr("href")!; - const img = $(el).find("img").attr("data-src")!; - - const altTitles: string[] = []; - const jpName = $(el).find("div.film-detail h3.film-name a.dynamic-name").attr("data-jname")!.trim().replace(/\\n/g, ""); - altTitles.push(jpName); - - const formatString: string = $(el).find("div.film-detail div.fd-infor span.fdi-item")?.first()?.text().toUpperCase(); - const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; - - results.push({ - id: id, - title: title, - altTitles: altTitles, - year: 0, - format, - img: img, - providerId: this.id, - }); - }); - - return results; - } - - override async fetchEpisodes(id: string): Promise { - const episodes: Episode[] = []; - - const data = await ( - await this.request(`${this.url}/ajax/v2/episode/list/${id.split("-").pop()}`, { - headers: { - "X-Requested-With": "XMLHttpRequest", - Referer: `${this.url}/watch/${id}`, - }, - }) - ).json(); - - const $ = load(data.html); - - const hasDubCheck = await (await this.request(`${this.url}/watch${id}`)).text(); - const $$ = load(hasDubCheck); - - const subDub = $$("div.film-stats div.tick-dub") - .toArray() - .map((value) => $$(value).text().toLowerCase()); - const dubCount = subDub.length >= 1 ? parseInt(subDub[0]) : false; - - $("div.detail-infor-content > div > a").map((i, el) => { - const number = parseInt($(el).attr("data-number")!); - const title = $(el).attr("title")!; - const id = $(el).attr("href")!; - const isFiller = $(el).hasClass("ssl-item-filler")!; - - episodes.push({ - id, - isFiller, - number, - title, - img: null, - hasDub: dubCount ? number <= dubCount : false, - }); - }); - - return episodes; - } - - override async fetchSources(id: string, subType: SubType = SubType.SUB, server: StreamingServers = StreamingServers.VidCloud): Promise { - const result: Source = { - sources: [], - subtitles: [], - audio: [], - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - headers: this.headers ?? {}, - }; - - if (id.startsWith("http")) { - const serverURL = id; - - return await new Extractor(serverURL, result).extract(server); - } - - const data = await (await this.request(`${this.url}/ajax/v2/episode/servers?episodeId=${id.split("?ep=")[1]}`)).json(); - const $ = load(data.html); - - /** - * vidtreaming -> 4 - * rapidcloud -> 1 - * streamsb -> 5 - * streamtape -> 3 - */ - let serverId; - switch (server) { - case StreamingServers.VidCloud: - serverId = this.retrieveServerId($, 4, subType); - - if (!serverId) throw new Error("RapidCloud not found"); - break; - case StreamingServers.VidStreaming: - serverId = this.retrieveServerId($, 4, subType); - - if (!serverId) throw new Error("VidStreaming not found"); - break; - case StreamingServers.StreamSB: - serverId = this.retrieveServerId($, 5, subType); - - if (!serverId) throw new Error("StreamSB not found"); - break; - case StreamingServers.StreamTape: - serverId = this.retrieveServerId($, 3, subType); - - if (!serverId) throw new Error("StreamTape not found"); - break; - default: - throw new Error("Server not found"); - } - - const req = await (await this.request(`${this.url}/ajax/v2/episode/sources?id=${serverId}`)).json(); - return await this.fetchSources(req.link, subType, server); - } - - private retrieveServerId($: any, index: number, subOrDub: SubType) { - return $(`div.ps_-block.ps_-block-sub.servers-${subOrDub} > div.ps__-list > div`) - .map((i: any, el: any) => ($(el).attr("data-server-id") === `${index}` ? $(el) : null)) - .get()[0] - ?.attr("data-id")!; - } -} diff --git a/anify-backend/src/mapping/impl/information/anilist.ts b/anify-backend/src/mapping/impl/information/anilist.ts deleted file mode 100644 index 4c0ccba..0000000 --- a/anify-backend/src/mapping/impl/information/anilist.ts +++ /dev/null @@ -1,1297 +0,0 @@ -import { Anime, Artwork, Character, Format, Genres, Manga, MediaStatus, Relations, Season, Type } from "../.."; -import InformationProvider, { AnimeInfo, MangaInfo, MediaInfoKeys } from "."; -import { anilistMediaGenerator } from "../../../helper/generator"; - -export default class AniList extends InformationProvider { - override id = "anilist"; - override url = "https://anilist.co"; - - private api = "https://graphql.anilist.co"; - - override get priorityArea(): MediaInfoKeys[] { - return ["bannerImage", "relations", "color"]; - } - - override get sharedArea(): MediaInfoKeys[] { - return ["synonyms", "genres", "tags", "artwork", "characters"]; - } - - override async search(query: string, type: Type, formats: Format[], page?: number, perPage?: number): Promise { - const aniListArgs = { - query: ` - query($page: Int, $perPage: Int, $search: String, $type: MediaType, $format: [MediaFormat]) { - Page(page: $page, perPage: $perPage) { - pageInfo { - total - currentPage - lastPage - hasNextPage - perPage - } - media(type: $type, format_in: $format, search: $search) { - ${this.query} - } - } - } - `, - variables: { - search: query, - type: type, - format: formats, - page: page ? page : 0, - perPage: perPage ? perPage : 15, - }, - }; - const req = await this.request( - this.api, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - origin: "graphql.anilist.co", - }, - body: JSON.stringify(aniListArgs), - }, - true - ); - const json = await req?.json(); - const media = json.data.Page.media; - - if (type === Type.ANIME) { - return media.map((data: Media) => { - const artwork: Artwork[] = []; - - if (data.coverImage.large) - artwork.push({ - type: "poster", - img: data.coverImage.large, - providerId: this.id, - }); - if (data.coverImage.extraLarge) - artwork.push({ - type: "poster", - img: data.coverImage.extraLarge, - providerId: this.id, - }); - if (data.bannerImage) - artwork.push({ - type: "banner", - img: data.bannerImage, - providerId: this.id, - }); - - const characters: Character[] = []; - const relations: Relations[] = []; - - for (const character of data.characters.edges) { - if (characters.length > 10) break; - const aliases: string[] = []; - - for (const alias of character.node.name.alternative) { - aliases.push(alias); - } - aliases.push(character.node.name.full); - - characters.push({ - voiceActor: { - name: character.voiceActors[0]?.name?.full ?? null, - image: character.voiceActors[0]?.image?.large ?? null, - }, - image: character.node.image.large, - name: character.node.name.full, - }); - } - - for (const relation of data.relations.edges) { - relations.push({ - id: String(relation.node.id), - format: relation.node.format, - relationType: relation.relationType, - title: relation.node.title, - type: relation.node.type, - }); - } - - return { - aniListId: data.id, - malId: data.idMal, - title: { - english: data.title.english ?? null, - romaji: data.title.romaji ?? null, - native: data.title.native ?? null, - }, - trailer: null, - currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, - duration: data.duration ?? null, - coverImage: data.coverImage.extraLarge ?? null, - bannerImage: data.bannerImage ?? null, - popularity: Number(data.popularity), - synonyms: data.synonyms ?? [], - totalEpisodes: data.episodes ?? 0, - color: null, - status: data.status, - season: data.season as Season, - genres: (data.genres as Genres[]) ?? [], - rating: data.meanScore ? data.meanScore / 10 : null, - description: data.description ?? null, - format: data.format, - year: data.seasonYear ?? data.startDate?.year ?? null, - type: data.type, - countryOfOrigin: data.countryOfOrigin ?? null, - tags: data.tags.map((tag) => { - return tag.name; - }), - artwork: artwork, - relations: relations, - characters: characters, - } as AnimeInfo; - }); - } else { - return media.map((data: Media) => { - const artwork: Artwork[] = []; - - if (data.coverImage.large) - artwork.push({ - type: "poster", - img: data.coverImage.large, - providerId: this.id, - }); - if (data.coverImage.extraLarge) - artwork.push({ - type: "poster", - img: data.coverImage.extraLarge, - providerId: this.id, - }); - if (data.bannerImage) - artwork.push({ - type: "banner", - img: data.bannerImage, - providerId: this.id, - }); - - const characters: Character[] = []; - const relations: Relations[] = []; - - for (const character of data.characters.edges) { - if (characters.length > 10) break; - const aliases: string[] = []; - - for (const alias of character.node.name.alternative) { - aliases.push(alias); - } - aliases.push(character.node.name.full); - - characters.push({ - voiceActor: { - name: character.voiceActors[0]?.name?.full ?? null, - image: character.voiceActors[0]?.image?.large ?? null, - }, - image: character.node.image.large, - name: character.node.name.full, - }); - } - - for (const relation of data.relations.edges) { - relations.push({ - id: String(relation.node.id), - format: relation.node.format, - relationType: relation.relationType, - title: relation.node.title, - type: relation.node.type, - }); - } - - return { - aniListId: data.id, - malId: data.idMal, - title: { - english: data.title.english ?? null, - romaji: data.title.romaji ?? null, - native: data.title.native ?? null, - }, - coverImage: data.coverImage.extraLarge ?? null, - bannerImage: data.bannerImage ?? null, - popularity: Number(data.popularity), - synonyms: data.synonyms ?? [], - totalChapters: data.chapters ?? 0, - totalVolumes: data.volumes ?? 0, - color: null, - status: data.status, - genres: (data.genres as Genres[]) ?? [], - rating: data.meanScore ? data.meanScore / 10 : null, - description: data.description ?? null, - format: data.format, - year: data.seasonYear ?? data.startDate?.year ?? null, - type: data.type, - countryOfOrigin: data.countryOfOrigin ?? null, - tags: data.tags.map((tag) => tag.name), - artwork: artwork, - characters: characters, - relations: relations, - } as MangaInfo; - }); - } - } - - public async searchAdvanced(query: string, type: Type, formats: Format[], page: number, perPage: number, genres: Genres[] = [], genresExcluded: Genres[] = [], year = 0, tags: string[] = [], tagsExcluded: string[] = []): Promise { - const aniListArgs: { query: string; variables: { [key: string]: any } } = { - query: ` - query ($page: Int, $perPage: Int, $search: String, $type: MediaType, $format: [MediaFormat], $genres: [String], $genresExcluded: [String], $tags: [String], $tagsExcluded: [String]) { - Page(page: $page, perPage: $perPage) { - pageInfo { - total - currentPage - lastPage - hasNextPage - perPage - } - media(type: $type, format_in: $format, search: $search, genre_in: $genres, genre_not_in: $genresExcluded, tag_in: $tags, tag_not_in: $tagsExcluded) { - ${this.query} - } - } - } - `, - variables: { - search: query, - type: type, - format: formats, - page: page, - perPage: perPage, - genres: genres, - genresExclude: genresExcluded, - tags: tags.length > 0 ? tags : undefined, - tagsExclude: tagsExcluded, - }, - }; - - if (tags.length === 0) delete aniListArgs.variables.tags; - - const req = await this.request( - this.api, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - origin: "graphql.anilist.co", - }, - body: JSON.stringify(aniListArgs), - }, - true - ); - const json = await req?.json(); - const media = json.data.Page.media; - - if (type === Type.ANIME) { - return media.map((data: Media) => { - const artwork: Artwork[] = []; - - if (data.coverImage.large) - artwork.push({ - type: "poster", - img: data.coverImage.large, - providerId: this.id, - }); - if (data.coverImage.extraLarge) - artwork.push({ - type: "poster", - img: data.coverImage.extraLarge, - providerId: this.id, - }); - if (data.bannerImage) - artwork.push({ - type: "banner", - img: data.bannerImage, - providerId: this.id, - }); - - const characters: Character[] = []; - const relations: Relations[] = []; - - for (const character of data.characters.edges) { - if (characters.length > 10) break; - const aliases: string[] = []; - - for (const alias of character.node.name.alternative) { - aliases.push(alias); - } - aliases.push(character.node.name.full); - - characters.push({ - voiceActor: { - name: character.voiceActors[0]?.name?.full ?? null, - image: character.voiceActors[0]?.image?.large ?? null, - }, - image: character.node.image.large, - name: character.node.name.full, - }); - } - - for (const relation of data.relations.edges) { - relations.push({ - id: String(relation.node.id), - format: relation.node.format, - relationType: relation.relationType, - title: relation.node.title, - type: relation.node.type, - }); - } - - return { - aniListId: data.id, - malId: data.idMal, - title: { - english: data.title.english ?? null, - romaji: data.title.romaji ?? null, - native: data.title.native ?? null, - }, - trailer: null, - currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, - duration: data.duration ?? null, - coverImage: data.coverImage.extraLarge ?? null, - bannerImage: data.bannerImage ?? null, - popularity: Number(data.popularity), - synonyms: data.synonyms ?? [], - totalEpisodes: data.episodes ?? 0, - color: null, - status: data.status, - season: data.season as Season, - genres: (data.genres as Genres[]) ?? [], - rating: data.meanScore ? data.meanScore / 10 : null, - description: data.description ?? null, - format: data.format, - year: data.seasonYear ?? data.startDate?.year ?? null, - type: data.type, - countryOfOrigin: data.countryOfOrigin ?? null, - tags: data.tags.map((tag) => { - return tag.name; - }), - artwork: artwork, - relations: relations, - characters: characters, - } as AnimeInfo; - }); - } else { - return media.map((data: Media) => { - const artwork: Artwork[] = []; - - if (data.coverImage.large) - artwork.push({ - type: "poster", - img: data.coverImage.large, - providerId: this.id, - }); - if (data.coverImage.extraLarge) - artwork.push({ - type: "poster", - img: data.coverImage.extraLarge, - providerId: this.id, - }); - if (data.bannerImage) - artwork.push({ - type: "banner", - img: data.bannerImage, - providerId: this.id, - }); - - const characters: Character[] = []; - const relations: Relations[] = []; - - for (const character of data.characters.edges) { - if (characters.length > 10) break; - const aliases: string[] = []; - - for (const alias of character.node.name.alternative) { - aliases.push(alias); - } - aliases.push(character.node.name.full); - - characters.push({ - voiceActor: { - name: character.voiceActors[0]?.name?.full ?? null, - image: character.voiceActors[0]?.image?.large ?? null, - }, - image: character.node.image.large, - name: character.node.name.full, - }); - } - - for (const relation of data.relations.edges) { - relations.push({ - id: String(relation.node.id), - format: relation.node.format, - relationType: relation.relationType, - title: relation.node.title, - type: relation.node.type, - }); - } - - return { - aniListId: data.id, - malId: data.idMal, - title: { - english: data.title.english ?? null, - romaji: data.title.romaji ?? null, - native: data.title.native ?? null, - }, - coverImage: data.coverImage.extraLarge ?? null, - bannerImage: data.bannerImage ?? null, - popularity: Number(data.popularity), - synonyms: data.synonyms ?? [], - totalChapters: data.chapters ?? 0, - totalVolumes: data.volumes ?? 0, - color: null, - status: data.status, - genres: (data.genres as Genres[]) ?? [], - rating: data.meanScore ? data.meanScore / 10 : null, - description: data.description ?? null, - format: data.format, - year: data.seasonYear ?? data.startDate?.year ?? null, - type: data.type, - countryOfOrigin: data.countryOfOrigin ?? null, - tags: data.tags.map((tag) => tag.name), - artwork: artwork, - characters: characters, - relations: relations, - } as MangaInfo; - }); - } - } - - override async info(media: Anime | Manga): Promise { - const anilistId = media.id; - - const query = `query ($id: Int) { - Media (id: $id) { - ${this.query} - } - }`; - const variables = { - id: anilistId, - }; - - const req = await this.request( - this.api, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - origin: "graphql.anilist.co", - }, - body: JSON.stringify({ - query, - variables, - }), - }, - true - ); - //const data: Media = (await req.json()).data.Media; - const text = await req.text(); - let data: any = undefined; - try { - data = JSON.parse(text).data.Media; - } catch (e) { - console.log(text); - } - if (!data) throw new Error("No data returned from AniList"); - - const artwork: Artwork[] = []; - - if (data.coverImage.large) - artwork.push({ - type: "poster", - img: data.coverImage.large, - providerId: this.id, - }); - if (data.coverImage.extraLarge) - artwork.push({ - type: "poster", - img: data.coverImage.extraLarge, - providerId: this.id, - }); - if (data.bannerImage) - artwork.push({ - type: "banner", - img: data.bannerImage, - providerId: this.id, - }); - - const characters: Character[] = []; - const relations: Relations[] = []; - - for (const character of data.characters.edges) { - if (characters.length > 10) break; - const aliases: string[] = []; - - for (const alias of character.node.name.alternative) { - aliases.push(alias); - } - aliases.push(character.node.name.full); - - characters.push({ - voiceActor: { - name: character.voiceActors[0]?.name?.full ?? null, - image: character.voiceActors[0]?.image?.large ?? null, - }, - image: character.node.image.large, - name: character.node.name.full, - }); - } - - for (const relation of data.relations.edges) { - relations.push({ - id: String(relation.node.id), - format: relation.node.format, - relationType: relation.relationType, - title: relation.node.title, - type: relation.node.type, - }); - } - - return { - title: { - english: data.title.english ?? null, - romaji: data.title.romaji ?? null, - native: data.title.native ?? null, - }, - trailer: null, - currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, - duration: data.duration ?? null, - coverImage: data.coverImage.extraLarge ?? null, - bannerImage: data.bannerImage ?? null, - popularity: Number(data.popularity), - synonyms: data.synonyms ?? [], - totalEpisodes: data.episodes ?? 0, - totalChapters: data.chapters ?? 0, - totalVolumes: data.volumes ?? 0, - color: data.coverImage.color ?? null, - status: data.status as MediaStatus, - season: data.season as Season, - genres: (data.genres as Genres[]) ?? [], - rating: data.meanScore ? data.meanScore / 10 : null, - description: data.description ?? null, - format: data.format, - year: data.seasonYear ?? data.startDate?.year ?? null, - countryOfOrigin: data.countryOfOrigin ?? null, - tags: data.tags.map((tag: { name: string }) => tag.name), - relations: relations, - artwork, - characters, - }; - } - - public getCurrentSeason(): Season { - return Season.SUMMER; - } - - public async getMedia(id: string): Promise { - const query = `query ($id: Int) { - Media (id: $id) { - ${this.query} - } - }`; - const variables = { - id: id, - }; - - const req = await this.request( - this.api, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - origin: "graphql.anilist.co", - }, - body: JSON.stringify({ - query, - variables, - }), - }, - true - ); - const data: Media = (await req.json()).data?.Media; - if (!data) return undefined; - - const characters: Character[] = []; - const relations: Relations[] = []; - - for (const character of data.characters.edges) { - if (characters.length > 10) break; - const aliases: string[] = []; - - for (const alias of character.node.name.alternative) { - aliases.push(alias); - } - aliases.push(character.node.name.full); - - characters.push({ - voiceActor: { - name: character.voiceActors[0]?.name?.full ?? null, - image: character.voiceActors[0]?.image?.large ?? null, - }, - image: character.node.image.large, - name: character.node.name.full, - }); - } - - for (const relation of data.relations.edges) { - relations.push({ - id: String(relation.node.id), - format: relation.node.format, - relationType: relation.relationType, - title: relation.node.title, - type: relation.node.type, - }); - } - - return { - id: data.id, - idMal: data.idMal, - title: { - english: data.title.english ?? null, - romaji: data.title.romaji ?? null, - native: data.title.native ?? null, - }, - trailer: null, - currentEpisode: data.status === MediaStatus.FINISHED || data.status === MediaStatus.CANCELLED ? data.episodes ?? 0 : 0, - duration: data.duration ?? null, - coverImage: data.coverImage.extraLarge ?? null, - bannerImage: data.bannerImage ?? null, - popularity: Number(data.popularity), - synonyms: data.synonyms ?? [], - totalEpisodes: data.episodes ?? 0, - totalChapters: data.chapters ?? 0, - color: null, - status: data.status as MediaStatus, - season: data.season as Season, - genres: (data.genres as Genres[]) ?? [], - rating: data.meanScore ? data.meanScore / 10 : null, - description: data.description ?? null, - format: data.format, - year: data.seasonYear ?? data.startDate?.year ?? null, - streamingEpisodes: data.streamingEpisodes ?? [], - type: data.type, - countryOfOrigin: data.countryOfOrigin ?? null, - tags: data.tags.map((tag) => tag.name), - isAdult: data.isAdult, - relations, - characters, - } as any; - } - - public async fetchSeasonal(type: Type, formats: Format[]) { - const aniListArgs = { - query: ` - query($season: MediaSeason, $seasonYear: Int, $format: [MediaFormat], $page: Int, $perPage: Int, $type: MediaType) { - trending: Page(page: $page, perPage: $perPage) { - media(sort: TRENDING_DESC, type: $type, isAdult: false, format_in: $format) { - ...media - } - } - season: Page(page: $page, perPage: $perPage) { - media(season: $season, seasonYear: $seasonYear, sort: POPULARITY_DESC, type: $type, isAdult: false, format_in: $format) { - ...media - } - } - popular: Page(page: $page, perPage: $perPage) { - media(sort: POPULARITY_DESC, type: $type, isAdult: false, format_in: $format) { - ...media - } - } - top: Page(page: $page, perPage: $perPage) { - media(sort: SCORE_DESC, type: $type, isAdult: false, format_in: $format) { - ...media - } - } - } - - fragment media on Media { - ${this.query} - } - `, - variables: { - type: type, - season: this.getCurrentSeason(), - seasonYear: 2023, - format: formats, - page: 0, - perPage: 20, - }, - }; - - const req = await ( - await this.request( - this.api, - { - body: JSON.stringify(aniListArgs), - method: "POST", - headers: { - "Content-Type": "application/json", - Origin: "https://anilist.co", - }, - }, - true - ) - ).json(); - - const data = req?.data; - if (!data) { - return undefined; - } - - const trending = data.trending.media?.map((data: Media) => { - return anilistMediaGenerator(data); - }); - - const seasonal = data.season.media?.map((data: Media) => { - return anilistMediaGenerator(data); - }); - - const popular = data.popular.media?.map((data: Media) => { - return anilistMediaGenerator(data); - }); - - const top = data.top.media?.map((data: Media) => { - return anilistMediaGenerator(data); - }); - - return { - trending, - seasonal, - popular, - top, - }; - } - - public async fetchSchedule(): Promise { - const currentDate = new Date(); // Get the current date - - const fetchData = async (page = 1) => { - // Calculate the start date of the week (assuming Monday as the first day of the week) - const weekStart = new Date(currentDate); - weekStart.setDate(currentDate.getDate() - currentDate.getDay() + 1); // Set to Monday - - // Calculate the end date of the week (assuming Sunday as the last day of the week) - const weekEnd = new Date(currentDate); - weekEnd.setDate(currentDate.getDate() - currentDate.getDay() + 8); // Set to next Monday - - const aniListArgs = { - query: ` - query( - $weekStart: Int, - $weekEnd: Int, - $page: Int - ) { - Page(page: $page) { - pageInfo { - hasNextPage - total - } - airingSchedules( - airingAt_greater: $weekStart airingAt_lesser: $weekEnd - ) { - id - episode - airingAt - media { - - id - idMal - title { - romaji - native - english - } - startDate { - year - month - day - } - endDate { - year - month - day - } - status - season - format - genres - synonyms - duration - popularity - episodes - source(version: 2) - countryOfOrigin - hashtag - averageScore - siteUrl - description - bannerImage - isAdult - coverImage { - extraLarge - color - } - trailer { - id - site - thumbnail - } - externalLinks { - site - url - } - rankings { - rank - type - season - allTime - } - studios(isMain: true) { - nodes { - id - name - siteUrl - } - } - relations { - edges { - relationType(version: 2) - node { - id - title { - romaji - native - english - } - siteUrl - } - } - } - } - } - } - } - `, - variables: { - weekStart: Math.round(weekStart.getTime() / 1000), - weekEnd: Math.round(weekEnd.getTime() / 1000), - page, - }, - }; - - const req = await ( - await this.request( - this.api, - { - body: JSON.stringify(aniListArgs), - method: "POST", - headers: { - "Content-Type": "application/json", - Origin: "https://anilist.co", - }, - }, - true - ) - ).json(); - - const schedule: Schedule[] = req?.data.Page.airingSchedules; - - return schedule; - }; - - const pages = [1, 2, 3, 4, 5, 6, 7]; - const fetchDataPromises = pages.map(fetchData); - - const results = await Promise.all(fetchDataPromises); - const schedule = results.flat(); - - return schedule; - } - - public async batchRequest(queries: string[], maxQueries: number): Promise { - const results: any[] = []; - - const processBatch = async (batch: string[]) => { - const currentQuery = `{${batch.join("\n")}}`; - const result = await this.executeGraphQLQuery(currentQuery); - if (result) { - const data = await result.json(); - results.push(...Object.values(data)); - } - }; - - const batchedQueries: string[][] = []; - for (let i = 0; i < queries.length; i += maxQueries) { - batchedQueries.push(queries.slice(i, i + maxQueries)); - } - - for await (const batch of batchedQueries) { - await processBatch(batch); - } - - return results; - } - - private async executeGraphQLQuery(query: string) { - const variables = {}; - return await this.request( - this.api, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - origin: "graphql.anilist.co", - }, - body: JSON.stringify({ - query, - variables, - }), - }, - true - ).catch((err) => { - console.error(err); - return null; - }); - } - - public query = ` - id - idMal - title { - romaji - english - native - userPreferred - } - coverImage { - extraLarge - large - color - } - bannerImage - startDate { - year - month - day - } - endDate { - year - month - day - } - description - season - seasonYear - type - format - status(version: 2) - episodes - duration - chapters - volumes - genres - synonyms - source(version: 3) - isAdult - meanScore - averageScore - popularity - favourites - countryOfOrigin - isLicensed - characters { - edges { - voiceActors { - id - name { - first - middle - last - full - native - } - image { - large - } - gender - age - dateOfBirth { - year - month - day - } - languageV2 - } - role - node { - id - name { - first - middle - last - full - native - alternative - alternativeSpoiler - } - age - image { - large - } - description - modNotes - siteUrl - } - } - } - relations { - edges { - id - relationType(version: 2) - node { - id - title { - english - romaji - native - } - format - type - status(version: 2) - bannerImage - coverImage { - large - } - } - } - } - streamingEpisodes { - title - thumbnail - url - } - trailer { - id - site - } - tags { - id - name - } - `; -} - -interface Media { - id: number; - idMal: number; - title: { - english?: string; - romaji: string; - native: string; - userPreferred: string; - }; - coverImage: { - extraLarge: string; - large: string; - color?: string; - }; - bannerImage: string; - startDate: { - year: number; - month: number; - day: number; - }; - endDate: { - year: number; - month: number; - day: number; - }; - description: string; - season: "WINTER" | "SPRING" | "SUMMER" | "FALL"; - seasonYear: number; - type: Type; - format: Format; - status: "FINISHED" | "RELEASING" | "NOT_YET_RELEASED" | "CANCELLED"; - episodes?: number; - duration?: number; - chapters?: number; - volumes?: number; - genres: string[]; - synonyms: string[]; - source: "ORIGINAL" | "LIGHT_NOVEL" | "VISUAL_NOVEL" | "VIDEO_GAME" | "OTHER" | "NOVEL" | "MANGA" | "DOUJINSHI" | "ANIME" | "WEB_MANGA" | "BOOK" | "CARD_GAME" | "COMIC" | "GAME" | "MUSIC" | "NOVEL" | "ONE_SHOT" | "OTHER" | "PICTURE_BOOK" | "RADIO" | "TV" | "UNKNOWN"; - isAdult: boolean; - meanScore: number; - averageScore: number; - popularity: number; - favourites: number; - countryOfOrigin: string; - isLicensed: boolean; - airingSchedule: { - edges: { - node: { - airingAt?: any; - timeUntilAiring?: any; - episode?: any; - }; - }; - }; - relations: { - edges: [RelationsNode]; - }; - characters: { - edges: [ - { - role: string; - voiceActors: [ - { - id: number; - name: { - first: string; - middle: string; - last: string; - full: string; - native: string; - }; - languageV2: string; - image: { - large: string; - }; - gender: string | null; - age: number | null; - dateOfBirth: { - year: number | null; - month: number | null; - day: number | null; - }; - } - ]; - node: { - id: number; - name: { - first: string; - middle: string; - last: string; - full: string; - native: string; - alternative: string[]; - alternativeSpoiler: string[]; - }; - age: number | null; - image: { - large: string; - }; - description: string; - modNotes: string; - siteUrl: string; - }; - } - ]; - }; - studios: { - edges: { - isMain: boolean; - node: { - id: number; - name: string; - }; - }; - }; - streamingEpisodes: [ - { - title?: string; - thumbnail?: string; - url?: string; - } - ]; - trailer: { - id: string; - site: string; - }; - tags: [{ id: number; name: string }]; -} - -interface RelationsNode { - id: number; - relationType: string; - node: { - id: number; - title: { - english: string | null; - romaji: string | null; - native: string | null; - }; - format: Format; - type: Type; - status: string; - bannerImage: string; - coverImage: { - large: string; - }; - }; -} - -interface Schedule { - id: number; - episode: number; - airingAt: number; - media: { - id: number; - idMal: number; - title: { - romaji: string; - native: string; - english: string | null; - }; - startDate: { - year: number; - month: number; - day: number; - }; - endDate: { - year: number; - month: number; - day: number; - }; - status: string; - season: string | null; - format: string; - genres: string[]; - synonyms: string[]; - duration: number | null; - popularity: number; - episodes: number; - source: string; - countryOfOrigin: string; - hashtag: string | null; - averageScore: number | null; - siteUrl: string; - description: string | null; - bannerImage: string | null; - isAdult: boolean; - coverImage: { - extraLarge: string; - color: string; - }; - trailer: string | null; - externalLinks: { - site: string; - url: string; - }[]; - rankings: any[]; - studios: { - nodes: { - id: number; - name: string; - siteUrl: string; - }[]; - }; - relations: { - edges: any[]; - }; - }; -} diff --git a/anify-backend/src/mapping/impl/information/comicK.ts b/anify-backend/src/mapping/impl/information/comicK.ts deleted file mode 100644 index 4fd43e1..0000000 --- a/anify-backend/src/mapping/impl/information/comicK.ts +++ /dev/null @@ -1,152 +0,0 @@ -import InformationProvider, { AnimeInfo, MangaInfo, MediaInfoKeys } from "."; -import { Anime, Artwork, Format, Genres, Manga, MediaStatus, Season, Type } from "../.."; - -export default class ComicKInfo extends InformationProvider { - override id = "comick"; - override url = "https://comick.app"; - - // Docs: https://upload.comick.app/docs/static/index.html - private api = "https://api.comick.fun"; - - override get priorityArea(): MediaInfoKeys[] { - return ["coverImage", "description"]; - } - - override get sharedArea(): MediaInfoKeys[] { - return ["synonyms", "genres", "artwork", "tags"]; - } - - override async info(media: Anime | Manga): Promise { - const comicKId = media.mappings.find((data) => { - return data.providerId === "comick"; - })?.id; - - if (!comicKId) return undefined; - - const req = await this.request(`${this.api}/comic/${comicKId}`, {}, true); - - if (!req.ok) return undefined; - - const coverReq = await this.request(`${this.api}/comic/${comicKId}/covers`, {}, true); - const covers: Covers = await coverReq.json(); - - const data: Comic = (await req.json()).comic; - - return { - artwork: covers.md_covers.map((cover) => { - return { - img: "https://meo.comick.pictures/" + cover.b2key, - type: "poster", - providerId: this.id, - }; - }), - bannerImage: null, - characters: [], - color: null, - countryOfOrigin: data.country, - coverImage: - covers.md_covers.map((cover) => { - if (cover.is_primary) { - return `https://meo.comick.pictures/${cover.b2key}`; - } - })[0] ?? - data.md_covers.map((cover) => `https://meo.comick.pictures/${cover.b2key}`)[0] ?? - null, - currentEpisode: null, - description: data.desc, - duration: null, - format: Format.UNKNOWN, - genres: - (data.md_comic_md_genres.map((genre) => { - return genre.md_genres.name; - }) as Genres[]) ?? [], - popularity: Number(data.user_follow_count), - rating: Number(data.bayesian_rating), - relations: [], - season: Season.UNKNOWN, - status: data.status === 1 ? MediaStatus.FINISHED : MediaStatus.RELEASING, - synonyms: data.md_titles.map((title) => title.title), - tags: data.mu_comics.mu_comic_categories.map((genre) => { - return genre.mu_categories.title; - }), - title: { - english: data.md_titles.find((title) => title.lang === "en")?.title ?? data.title, - native: data.md_titles.find((title) => title.lang === "ja")?.title ?? null, - romaji: data.md_titles.find((title) => title.lang === "ja-ro")?.title ?? null, - }, - totalChapters: data.chapter_count, - totalVolumes: null, - trailer: null, - year: data.year, - }; - } -} - -interface Comic { - id: number; - hid: string; - title: string; - country: string; - status: number; - links: { al: string; ap: string; bw: string; kt: string; mu: string; amz: string; cdj: string; ebj: string; mal: string; raw: string }; - last_chapter: any; - chapter_count: number; - demographic: number; - hentai: boolean; - user_follow_count: number; - follow_rank: number; - comment_count: number; - follow_count: number; - desc: string; - parsed: string; - slug: string; - mismatch: any; - year: number; - bayesian_rating: any; - rating_count: number; - content_rating: string; - translation_completed: boolean; - relate_from: Array; - mies: any; - md_titles: { title: string; lang?: string }[]; - md_comic_md_genres: { md_genres: { name: string; type: string | null; slug: string; group: string } }[]; - mu_comics: { - licensed_in_english: any; - mu_comic_categories: { - mu_categories: { title: string; slug: string }; - positive_vote: number; - negative_vote: number; - }[]; - }; - md_covers: { vol: any; w: number; h: number; b2key: string }[]; - iso639_1: string; - lang_name: string; - lang_native: string; -} - -interface Covers { - id: number; - title: string; - slug: string; - links2: { - id: string; - slug: string; - enable: boolean; - }[]; - noindex: boolean; - country: string; - md_covers: { - id: number; - w: number; - h: number; - s: number; - gpurl: string; - md_comic_id: number; - url: string; - vol: string; - mdid: string | null; - b2key: string; - is_primary: boolean; - locale: string | boolean; - }[]; -} diff --git a/anify-backend/src/mapping/impl/information/index.ts b/anify-backend/src/mapping/impl/information/index.ts deleted file mode 100644 index dd699bc..0000000 --- a/anify-backend/src/mapping/impl/information/index.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Anime, Format, Manga, ProviderType, Type } from "../.."; -import Http from "../request"; - -export default abstract class InformationProvider { - abstract id: string; - abstract url: string; - - public providerType: ProviderType = ProviderType.INFORMATION; - public customProxy: string | undefined; - - async search(query: string, type: Type, formats: Format[]): Promise { - return []; - } - - async info(media: T): Promise { - return undefined; - } - - get priorityArea(): MediaInfoKeys[] { - return []; - } - - get sharedArea(): MediaInfoKeys[] { - return []; - } - - async request(url: string, config: RequestInit = {}, proxyRequest = true): Promise { - return Http.request(url, config, proxyRequest, 0, this.customProxy); - } -} - -export type AnimeInfo = Pick & { - rating: number | null; - popularity: number | null; -}; - -export type MangaInfo = Pick & { - rating: number | null; - popularity: number | null; -}; - -type SharedKeys = { - [K in keyof T]: K extends keyof U ? K : never; -}[keyof T]; - -export type MediaInfoKeys = SharedKeys; diff --git a/anify-backend/src/mapping/impl/information/kitsu.ts b/anify-backend/src/mapping/impl/information/kitsu.ts deleted file mode 100644 index 288ec14..0000000 --- a/anify-backend/src/mapping/impl/information/kitsu.ts +++ /dev/null @@ -1,160 +0,0 @@ -import InformationProvider, { AnimeInfo, MangaInfo, MediaInfoKeys } from "."; -import { Anime, Artwork, Format, Manga, Season } from "../.."; -export default class Kitsu extends InformationProvider { - override id = "kitsu"; - override url = "https://kitsu.io"; - - private kitsuApiUrl = "https://kitsu.io/api/edge"; - - override get priorityArea(): MediaInfoKeys[] { - return ["coverImage"]; - } - - override get sharedArea(): MediaInfoKeys[] { - return ["synonyms", "genres", "artwork"]; - } - - override async info(media: Anime | Manga): Promise { - const kitsuId = media.mappings.find((data) => { - return data.providerId === "kitsu"; - })?.id; - - if (!kitsuId) return undefined; - - const kitsuResponse: KitsuResponse = await (await this.request(`${this.kitsuApiUrl}/${media.type.toLowerCase()}/${kitsuId}`, {}, true)).json(); - - const attributes = kitsuResponse?.data?.attributes; - - if (!attributes) return undefined; - - const kitsuGenre = await (await this.request(`${this.kitsuApiUrl}/${media.type.toLowerCase()}/${kitsuId}/genres`, {}, true)).json(); - const genres = kitsuGenre?.data; - - const artwork: Artwork[] = []; - - if (attributes.coverImage?.original) - artwork.push({ - type: "banner", - img: attributes.coverImage.original, - providerId: this.id, - }); - if (attributes.posterImage?.original) - artwork.push({ - type: "poster", - img: attributes.posterImage.original, - providerId: this.id, - }); - - return { - title: { - english: attributes.titles.en ?? null, - romaji: attributes.titles.en_jp ?? null, - native: attributes.titles.ja_jp ?? null, - }, - currentEpisode: null, - trailer: null, - duration: attributes.episodeLength ?? null, - color: null, - bannerImage: attributes.coverImage?.original ?? null, - coverImage: attributes.posterImage?.original ?? null, - status: null, - format: Format.UNKNOWN, - season: Season.UNKNOWN, - synonyms: [], - description: attributes.synopsis ?? null, - year: null, - totalEpisodes: attributes.episodeCount ?? 0, - genres: genres ? genres.map((genre: any) => genre.attributes.name) : [], - rating: attributes.averageRating ? Number.parseFloat((Number.parseFloat(attributes.averageRating) / 10).toFixed(2)) : null, - popularity: null, - countryOfOrigin: null, - tags: [], - relations: [], - artwork, - characters: [], - }; - } - - public async getEpisodeCovers(id: string): Promise<{ episode: number; img: string }[]> { - const episodeCovers: { episode: number; img: string }[] = []; - - let hasNext = true; - let page = 0; - const maxRetries = 3; - let retries = 0; - - while (hasNext && retries < maxRetries) { - const url = this.kitsuApiUrl + `/anime/${id}/episodes?page[limit]=20&page[offset]=${page * 20}`; - - const headers = { - Accept: "application/vnd.api+json", - "Content-Type": "application/vnd.api+json", - }; - - let req; - try { - req = await this.request(url, { headers }, true); - } catch (err) { - console.error(`Error fetching ${url}`, err); - retries++; - await new Promise((resolve) => setTimeout(resolve, 1000)); // wait 1 second before retrying - continue; - } - - if (!req) { - retries++; - await new Promise((resolve) => setTimeout(resolve, 1000)); // wait 1 second before retrying - continue; - } - - const data = await req.json().catch(undefined); - if (!data) { - retries++; - await new Promise((resolve) => setTimeout(resolve, 1000)); // wait 1 second before retrying - continue; - } - - for (let i = 0; i < data.data.length; i++) { - const episode = data.data[i]; - episodeCovers.push({ - episode: episode.attributes.relativeNumber, - img: episode.attributes.thumbnail?.original, - }); - } - - if (data.links.next) { - page++; - } else { - hasNext = false; - } - } - - return episodeCovers; - } -} - -type KitsuResponse = { - data: { - attributes: { - titles: { - en: string | null; - en_jp: string | null; - ja_jp: string | null; - }; - description: string | null; - subtype: string; - status: string; - showType: string; - synopsis: string | null; - episodeLength: number | null; - posterImage: { - original: string | null; - }; - coverImage: { - original: string | null; - }; - averageRating: string | null; - episodeCount: number | null; - }; - }; -}; diff --git a/anify-backend/src/mapping/impl/information/mal.ts b/anify-backend/src/mapping/impl/information/mal.ts deleted file mode 100644 index 4c42f08..0000000 --- a/anify-backend/src/mapping/impl/information/mal.ts +++ /dev/null @@ -1,97 +0,0 @@ -import InformationProvider, { AnimeInfo, MangaInfo, MediaInfoKeys } from "."; -import { Anime, Artwork, Format, Genres, Manga, MediaStatus, Season, Type } from "../.."; - -export default class MAL extends InformationProvider { - override id = "mal"; - override url = "https://myanimelist.net"; - - override get priorityArea(): MediaInfoKeys[] { - return []; - } - - override get sharedArea(): MediaInfoKeys[] { - return ["synonyms", "genres", "artwork"]; - } - - override async info(media: Anime | Manga): Promise { - const malId = media.mappings.find((data) => { - return data.providerId === "mal"; - })?.id; - - if (!malId) return undefined; - - const req = await this.request(`https://api.jikan.moe/v4/${media.type.toLowerCase()}/${malId}/full`, { - headers: { - origin: "https://jikan.moe", - }, - }); - - if (!req.ok) return undefined; - const jikanResponse = await req.json(); - - const data: JikanResponse = jikanResponse.data; - - if (!data) return undefined; - - const artwork: Artwork[] = []; - - if (data.images?.jpg?.image_url) - artwork.push({ - type: "poster", - img: data.images.jpg.image_url, - providerId: this.id, - }); - - return { - title: { - english: data.title_english ?? null, - romaji: data.title ?? null, - native: data.title_japanese ?? null, - }, - currentEpisode: data.status === "completed" ? data.episodes : null, - trailer: data.trailer ? data.trailer.url : null, - coverImage: data.images?.jpg?.image_url ?? null, - bannerImage: null, - color: null, - totalEpisodes: data.episodes ?? 0, - status: data.status ? ((data.status as string).toLowerCase() === "not yet aired" ? MediaStatus.NOT_YET_RELEASED : (data.status as string).toLowerCase() === "currently airing" ? MediaStatus.RELEASING : (data.status as string).toLowerCase() === "finished airing" ? MediaStatus.FINISHED : null) : null, - popularity: data.popularity, - synonyms: data.title_synonyms?.filter((s) => s?.length) ?? [], - season: data.season ? ([(data.season as string).toUpperCase()] as unknown as Season) : Season.UNKNOWN, - genres: data.genres ? (data.genres.map((g) => g.name) as Genres[]) : [], - description: data.synopsis ?? null, - rating: data.score ?? null, - year: data.year ?? null, - duration: data.duration ? Number.parseInt(data.duration.replace("min per ep", "").trim()) : null, - format: data.type.toUpperCase() as Format, - countryOfOrigin: null, - tags: [], - relations: [], - artwork, - characters: [], - }; - } -} - -type JikanResponse = { - title: string; - title_english: string | null; - title_japanese: string | null; - title_synonyms: string[]; - type: string; - status: string; - synopsis: string | null; - images: { - jpg: { - image_url: string | null; - }; - }; - duration: string; - episodes: number | null; - popularity: number | null; - score: number | null; - season: string; - year: number | null; - genres: { name: string }[]; - trailer: { url: string | null }; -}; diff --git a/anify-backend/src/mapping/impl/information/simkl.ts b/anify-backend/src/mapping/impl/information/simkl.ts deleted file mode 100644 index 104a494..0000000 --- a/anify-backend/src/mapping/impl/information/simkl.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { env } from "../../../env"; -import InformationProvider, { AnimeInfo, MangaInfo, MediaInfoKeys } from "."; -import { Anime, Artwork, Format, Manga, Season, Type } from "../.."; - -export default class Simkl extends InformationProvider { - override id = "simkl"; - override url = "https://simkl.com"; - - private simklKey = env.SIMKL_CLIENT_SECRET ?? ""; - private simklClient = env.SIMKL_CLIENT_ID ?? ""; - private simklApiUrl = "https://api.simkl.com"; - - override get priorityArea(): MediaInfoKeys[] { - return []; - } - - override get sharedArea(): MediaInfoKeys[] { - return ["synonyms", "genres", "artwork"]; - } - - override async info(media: Anime | Manga): Promise { - const simklId = media.mappings.find((data) => { - return data.providerId === "simkl"; - })?.id; - - if (!simklId) return undefined; - - const req = await this.request(`${this.simklApiUrl}/anime/${simklId}?extended=full&client_id=${this.simklClient}`); - const data: Information = await req.json(); - - const artwork: Artwork[] = []; - - if (data.poster) artwork.push({ img: `${this.url}/posters/${data.poster}_m.jpg`, type: "poster", providerId: this.id }); - if (data.fanart) artwork.push({ img: `${this.url}/posters/${data.fanart}_m.jpg`, type: "poster", providerId: this.id }); - - if (media.type === Type.ANIME) { - return { - title: { - english: data.en_title, - romaji: data.title, - native: null, - }, - synonyms: data.en_title ? [data.en_title] : [], - artwork: artwork, - bannerImage: null, - characters: [], - color: null, - countryOfOrigin: data.country, - coverImage: `${this.url}/posters/${data.poster}_m.jpg`, - currentEpisode: null, - description: data.overview, - duration: data.runtime, - format: Format.UNKNOWN, - genres: data.genres ?? [], - popularity: data.ratings?.simkl?.votes ?? 0, - rating: data.ratings?.simkl?.rating ?? 0, - relations: [], - season: Season.UNKNOWN, - status: null, - tags: [], - trailer: `https://youtube.com/watch?v=${data.trailers?.[0]?.youtube}`, - year: new Date(data.first_aired).getFullYear(), - totalEpisodes: data.total_episodes, - } as AnimeInfo; - } else { - return { - title: { - english: data.en_title, - romaji: data.title, - native: null, - }, - synonyms: data.en_title ? [data.en_title] : [], - artwork: artwork, - bannerImage: null, - characters: [], - color: null, - countryOfOrigin: data.country, - coverImage: `${this.url}/posters/${data.poster}_m.jpg`, - description: data.overview, - format: Format.UNKNOWN, - genres: data.genres ?? [], - popularity: data.ratings?.simkl?.votes ?? 0, - rating: data.ratings?.simkl?.rating ?? 0, - relations: [], - year: null, - status: null, - totalChapters: 0, - totalVolumes: 0, - tags: [], - } as MangaInfo; - } - } - - public async getEpisodeCovers(id: string): Promise<{ episode: number; img: string }[]> { - const episodeCovers: { episode: number; img: string }[] = []; - - const req = await this.request(`${this.simklApiUrl}/anime/episodes/${id}?client_id=${this.simklClient}`); - const data: Episode[] = await req.json(); - - for (const episode of data) { - if (!episode.img) continue; - episodeCovers.push({ - episode: episode.episode, - img: `https://simkl.in/episodes/${episode.img}_c.jpg`, - }); - } - - return episodeCovers; - } -} - -interface Information { - title: string; - year: number; - type: string; - ids: { - simkl: number; - slug: string; - anidb: string; - ann: string; - mal: string; - anfo: string; - wikien: string; - allcin: string; - imdb: string; - offjp: string; - crunchyroll: string; - anilist: string; - kitsu: string; - livechart: string; - anisearch: string; - animeplanet: string; - }; - en_title: string | null; - rank: number; - poster: string; - fanart: string; - first_aired: string; - airs: { - day: string; - time: string; - timezone: string; - }; - runtime: number; - certification: string | null; - overview: string; - genres: string[]; - country: string; - total_episodes: number; - status: string; - network: string; - anime_type: string; - ratings: { - simkl: { - rating: number; - votes: number; - }; - imdb: { - rating: number; - votes: number; - }; - mal: { - rating: number; - votes: number; - rank: number; - }; - }; - trailers: { - name: string | null; - youtube: string; - size: number; - }[]; - users_recommendations: { - title: string; - en_title: string | null; - year: number; - poster: string; - anime_type: string; - users_percent: string | number; - users_count: number; - ids: { - simkl: number; - slug: string; - }; - }[]; -} - -interface Episode { - title: string; - description: string | null; - episode: number; - type: string; - aired: boolean; - img: string; - date: string; - ids: { - simkl_id: number; - }; -} diff --git a/anify-backend/src/mapping/impl/information/tvdb.ts b/anify-backend/src/mapping/impl/information/tvdb.ts deleted file mode 100644 index 33a02c7..0000000 --- a/anify-backend/src/mapping/impl/information/tvdb.ts +++ /dev/null @@ -1,191 +0,0 @@ -import InformationProvider, { AnimeInfo, MangaInfo, MediaInfoKeys } from "."; -import { Anime, Character, Format, Manga, Season } from "../.."; -import colors from "colors"; - -export default class TVDB extends InformationProvider { - override id = "tvdb"; - override url = "https://thetvdb.com"; - - private tvdbApiUrl = "https://api4.thetvdb.com/v4"; - - private apiKeys = ["f5744a13-9203-4d02-b951-fbd7352c1657", "8f406bec-6ddb-45e7-8f4b-e1861e10f1bb", "5476e702-85aa-45fd-a8da-e74df3840baf", "51020266-18f7-4382-81fc-75a4014fa59f"]; - - override get priorityArea(): MediaInfoKeys[] { - return ["bannerImage", "coverImage"]; - } - - override get sharedArea(): MediaInfoKeys[] { - return ["synonyms", "genres", "tags", "artwork", "characters"]; - } - - override async info(media: Anime | Manga): Promise { - const tvdbId = media.mappings.find((data) => { - return data.providerId === "tvdb"; - })?.id; - - if (!tvdbId) return undefined; - - const token = await this.getToken(this.apiKeys[Math.floor(Math.random() * this.apiKeys.length)]); - - const data: Response | undefined = await this.request( - `${this.tvdbApiUrl}${tvdbId}/extended`, - { - headers: { - Authorization: `Bearer ${token}`, - }, - }, - false - ).catch((err) => { - try { - console.log(colors.red("TVDB Error: " + JSON.stringify(err?.response?.data)) + err?.response?.status); - console.log(colors.red("Request URL: ") + colors.yellow(`${this.tvdbApiUrl}${tvdbId}/extended`)); - } catch (e) { - console.log(colors.red("TVDB Error: " + err)); - } - return undefined; - }); - - if (!data) return undefined; - - if (data.ok) { - const info = (await data.json()).data; - - const img = info.image; - const aliases = info.aliases; - const firstAired = new Date(info.firstAired); - - const averageRunTime = info.averageRuntime; - - const characters: Character[] = (info.characters ?? []).map((character: any) => { - return { - name: character.name, - image: character.image, - voiceActor: { - name: character.peopleName, - image: character.peopleImageURL, - }, - }; - }); - - const artwork: Artwork[] = info.artworks; - - const artworkIds = { - banner: [1, 16, 6], - poster: [2, 7, 14, 27], - backgrounds: [3, 8, 15], - icon: [5, 10, 18, 19, 26], - clearArt: [22, 24], - clearLogo: [23, 25], - fanart: [11, 12], - actorPhoto: [13], - cinemagraphs: [20, 21], - }; - - const coverImages = artwork.filter((art) => artworkIds.poster.includes(Number(art.type))); - coverImages.sort((a, b) => b.score - a.score); - - const banners = artwork.filter((art) => artworkIds.backgrounds.includes(Number(art.type))); - banners.sort((a, b) => b.score - a.score); - - const genres = info.genres; - - const trailers = info.trailers; - - const airsDays = info.airsDays; // Helpful - - const artworkData = artwork - .map((art) => { - const type = artworkIds.backgrounds.includes(art.type) ? "banner" : artworkIds.banner.includes(art.type) ? "top_banner" : artworkIds.clearLogo.includes(art.type) ? "clear_logo" : artworkIds.poster.includes(art.type) ? "poster" : artworkIds.icon.includes(art.type) ? "icon" : artworkIds.clearArt.includes(art.type) ? "clear_art" : null; - if (!type) return; - return { - type: type, - img: art.image, - providerId: this.id, - }; - }) - .filter(Boolean); - - const hasPrequelRelation = media.relations.some((relation) => relation.relationType === "PREQUEL"); - const coverImage = hasPrequelRelation ? coverImages[0]?.image || img || null : media.coverImage?.length ?? 0 > 0 ? media.coverImage : coverImages[0]?.image || img || null; - - return { - title: { - english: null, - romaji: null, - native: null, - }, - currentEpisode: null, - trailer: trailers[0]?.url ?? null, - duration: averageRunTime ?? null, - color: null, - bannerImage: banners[0]?.image ?? null, - coverImage: coverImage, - status: null, - format: Format.UNKNOWN, - season: Season.UNKNOWN, - synonyms: aliases?.map((alias: { name: string }) => alias.name) ?? [], - description: null, - year: Number(info.year ?? firstAired.getFullYear()) ?? null, - totalEpisodes: 0, - genres: genres ? genres.map((genre: { name: string }) => genre.name) : [], - rating: null, - popularity: null, - countryOfOrigin: null, - tags: info.tags?.map((tag: { name: string }) => tag.name) ?? [], - relations: [], - artwork: artworkData as any, - characters: characters.slice(0, 10), - }; - } else { - console.log(colors.red("TVDB Error: " + JSON.stringify(await data.json()))); - } - - return undefined; - } - - private async getToken(key: string): Promise { - const data: Response | undefined = await this.request( - `${this.tvdbApiUrl}/login`, - { - body: JSON.stringify({ - apikey: `${key}`, - }), - method: "POST", - headers: { - "Content-Type": "application/json", - }, - }, - false - ).catch((err) => { - console.error(err); - return undefined; - }); - if (!data) return undefined; - - if (data.ok) { - return (await data.json()).data.token as string; - } - - return undefined; - } -} - -interface Artwork { - id: number; - image: string; - thumbnail: string; - language: null | string; - type: number; - score: number; - width: number; - height: number; - includesText: boolean; - thumbnailWidth: number; - thumbnailHeight: number; - updatedAt: number; - status: { - id: number; - name: null | string; - }; - tagOptions: null; -} diff --git a/anify-backend/src/mapping/impl/manga/comicK.ts b/anify-backend/src/mapping/impl/manga/comicK.ts deleted file mode 100644 index e87c52c..0000000 --- a/anify-backend/src/mapping/impl/manga/comicK.ts +++ /dev/null @@ -1,184 +0,0 @@ -import MangaProvider, { Chapter, Page } from "."; -import { Format, Result } from "../.."; -import colors from "colors"; - -export default class ComicK extends MangaProvider { - override rateLimit = 250; - override id = "comick"; - override url = "https://comick.app"; - - override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; - - // Docs: https://upload.comick.app/docs/static/index.html - private api = "https://api.comick.fun"; - - override async search(query: string, format?: Format, year?: number): Promise { - const data: SearchResult[] = await (await this.request(`${this.api}/v1.0/search?q=${encodeURIComponent(query)}&limit=25&page=1${year ? `&from=${year}&to=${year}` : ""}`, {}, true)).json(); - - const results: Result[] = []; - - for (let i = 0; i < data.length; i++) { - const result = data[i]; - - let cover: any = result.md_covers ? result.md_covers[0] : null; - if (cover && cover.b2key != undefined) { - cover = "https://meo.comick.pictures/" + cover.b2key; - } - - results.push({ - id: result.slug, - title: result.title ?? result.slug, - altTitles: result.md_titles ? result.md_titles.map((title) => title.title) : [], - img: cover, - format: format ?? Format.UNKNOWN, - year: year ?? 0, - providerId: this.id, - }); - } - - return results; - } - - override async fetchChapters(id: string): Promise { - const chapterList: Chapter[] = []; - - const comicId = await this.getComicId(`/comic/${id}`); - if (!comicId) { - return chapterList; - } - - const data = await (await this.request(`${this.api}/comic/${comicId}/chapters?lang=en&page=0&limit=1000000`, {}, true))?.json(); - - const chapters: Chapter[] = []; - - data.chapters.map((chapter: ComickChapter) => { - let title = ""; - - if (chapter.vol) { - title += "Vol. " + this.padNum(chapter.vol, 2) + " "; - } - if (chapter.chap) { - title += "Ch. " + this.padNum(chapter.chap, 2) + " "; - } - - let canPush = true; - for (let i = 0; i < chapters.length; i++) { - if (chapters[i].title === title) { - canPush = false; - } - } - - if (canPush) { - const updatedAt = new Date(chapter.updated_at ?? 0).getTime(); - if (chapter.lang === "en") { - chapters.push({ - id: chapter.hid, - title: title?.trim(), - number: Number(chapter.chap), - updatedAt, - }); - } - } - }); - - chapterList.push(...chapters); - - return chapterList; - } - - override async fetchPages(id: string): Promise { - const data = await (await this.request(`${this.api}/chapter/${id}`, {}, true))?.json(); - - const pages: Page[] = []; - - data.chapter.md_images.map((image: { vol: any; w: number; h: number; b2key: string }, index: number) => { - pages.push({ - url: `https://meo.comick.pictures/${image.b2key}?width=${image.w}`, - index: index, - headers: {}, - }); - }); - - return pages; - } - - private async getComicId(id: string): Promise { - const json = await (await this.request(`${this.api}${id}`, {}, true))?.json(); - const data: Comic = json.comic; - return data ? data.hid : null; - } -} - -interface SearchResult { - title: string; - id: number; - slug: string; - rating: string; - rating_count: number; - follow_count: number; - user_follow_count: number; - content_rating: string; - created_at: string; - demographic: number; - md_titles: { title: string }[]; - md_covers: { vol: any; w: number; h: number; b2key: string }[]; - highlight: string; -} - -interface Comic { - id: number; - hid: string; - title: string; - country: string; - status: number; - links: { al: string; ap: string; bw: string; kt: string; mu: string; amz: string; cdj: string; ebj: string; mal: string; raw: string }; - last_chapter: any; - chapter_count: number; - demographic: number; - hentai: boolean; - user_follow_count: number; - follow_rank: number; - comment_count: number; - follow_count: number; - desc: string; - parsed: string; - slug: string; - mismatch: any; - year: number; - bayesian_rating: any; - rating_count: number; - content_rating: string; - translation_completed: boolean; - relate_from: Array; - mies: any; - md_titles: { title: string }[]; - md_comic_md_genres: { md_genres: { name: string; type: string | null; slug: string; group: string } }[]; - mu_comics: { - licensed_in_english: any; - mu_comic_categories: { - mu_categories: { title: string; slug: string }; - positive_vote: number; - negative_vote: number; - }[]; - }; - md_covers: { vol: any; w: number; h: number; b2key: string }[]; - iso639_1: string; - lang_name: string; - lang_native: string; -} - -interface ComickChapter { - id: number; - chap: string; - title: string; - vol: string | null; - lang: string; - created_at: string; - updated_at: string; - up_count: number; - down_count: number; - group_name: any; - hid: string; - identities: any; - md_chapter_groups: { md_groups: { title: string; slug: string } }[]; -} diff --git a/anify-backend/src/mapping/impl/manga/index.ts b/anify-backend/src/mapping/impl/manga/index.ts deleted file mode 100644 index 49c9dbd..0000000 --- a/anify-backend/src/mapping/impl/manga/index.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Format, ProviderType, type Result } from "../.."; -import Http from "../request"; - -export default abstract class MangaProvider { - abstract rateLimit: number; - abstract id: string; - abstract url: string; - abstract formats: Format[]; - - public providerType: ProviderType = ProviderType.MANGA; - public customProxy: string | undefined; - - async search(query: string, format?: Format, year?: number): Promise { - return undefined; - } - - async fetchChapters(id: string): Promise { - return undefined; - } - - async fetchPages(id: string): Promise { - return undefined; - } - - async request(url: string, config: RequestInit = {}, proxyRequest = false): Promise { - return Http.request(url, config, proxyRequest, 0, this.customProxy); - } - - padNum(number: string, places: number): string { - // Credit to https://stackoverflow.com/a/10073788 - /* - * '17' - * '17.5' - * '17-17.5' - * '17 - 17.5' - * '17-123456789' - */ - let range = number.split("-"); - range = range.map((chapter) => { - chapter = chapter.trim(); - const digits = chapter.split(".")[0].length; - return "0".repeat(Math.max(0, places - digits)) + chapter; - }); - return range.join("-"); - } -} - -export type Chapter = { - id: string; - title: string; - number: number; - updatedAt?: number; - mixdrop?: string; -}; - -export type Page = { - url: string; - index: number; - headers: { [key: string]: string }; -}; diff --git a/anify-backend/src/mapping/impl/manga/jnovels.ts b/anify-backend/src/mapping/impl/manga/jnovels.ts deleted file mode 100644 index dbe76ed..0000000 --- a/anify-backend/src/mapping/impl/manga/jnovels.ts +++ /dev/null @@ -1,95 +0,0 @@ -import MangaProvider, { Chapter, Page } from "."; -import { Format, Result } from "../.."; -import { load } from "cheerio"; -import { compareTwoStrings } from "../../../helper/stringSimilarity"; - -export default class JNovels extends MangaProvider { - override rateLimit = 250; - override id = "jnovels"; - override url = "https://jnovels.com"; - - override formats: Format[] = [Format.NOVEL]; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - const list: Result[] = []; - - const req = await this.request(`${this.url}/11light-1novel20-pdf/`); - const $ = load(await req.text()); - - $("div.post-content ol li").map((i, el) => { - const id = $(el).find("a").attr("href")?.split(this.url)[1]!; - const title = $(el).find("a").text()?.trim() ?? ""; - - list.push({ - id: id, - title: title, - altTitles: [], - img: null, - year: 0, - format: Format.NOVEL, - providerId: this.id, - }); - }); - - for (const result of list) { - if (compareTwoStrings(query, result.title) > 0.3) { - results.push(result); - } - } - - if (results.length === 0) { - const req = await this.request(`${this.url}/hwebnovels-lista14/`); - const $ = load(await req.text()); - - $("div.post-content ol li").map((i, el) => { - const id = $(el).find("a").attr("href")!.split(this.url)[1]!; - const title = $(el).find("a").text()?.trim() ?? ""; - - list.push({ - id: id, - title: title, - altTitles: [], - img: null, - year: 0, - format: Format.NOVEL, - providerId: this.id, - }); - }); - - for (const result of list) { - if (compareTwoStrings(query, result.title) > 0.3) { - results.push(result); - } - } - } - - return results; - } - - override async fetchChapters(id: string): Promise { - const chapters: Chapter[] = []; - - const data = await (await this.request(`${this.url}${id}`)).text(); - - const $ = load(data); - - $("main div.post-content ol li").map((i, el) => { - const id = $(el).find("a").attr("href")!; - if (id && !id.includes(this.url)) { - const title = $(el).text()?.split(" ——")[0]; - chapters.push({ - id: id, - title: title?.trim(), - number: i + 1, - }); - } - }); - - return chapters; - } - - override async fetchPages(id: string): Promise { - return `No content able to read! You may download the novel
    here.`; - } -} diff --git a/anify-backend/src/mapping/impl/manga/mangadex.ts b/anify-backend/src/mapping/impl/manga/mangadex.ts deleted file mode 100644 index f1208cf..0000000 --- a/anify-backend/src/mapping/impl/manga/mangadex.ts +++ /dev/null @@ -1,178 +0,0 @@ -import { wait } from "../../../helper"; -import MangaProvider, { Chapter, Page } from "."; -import { Format, Formats, Result } from "../.."; - -export default class MangaDex extends MangaProvider { - override rateLimit = 250; - override id = "mangadex"; - override url = "https://mangadex.org"; - - override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; - - private api = "https://api.mangadex.org"; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - let mangaList: any[] = []; - - for (let page = 0; page <= 1; page += 1) { - const uri = new URL("/manga", this.api); - uri.searchParams.set("title", query); - uri.searchParams.set("limit", "25"); - uri.searchParams.set("offset", String(25 * page).toString()); - uri.searchParams.set("order[relevance]", "desc"); - uri.searchParams.append("contentRating[]", "safe"); - uri.searchParams.append("contentRating[]", "suggestive"); - uri.searchParams.append("contentRating[]", "erotica"); - uri.searchParams.append("contentRating[]", "pornographic"); - uri.searchParams.append("includes[]", "cover_art"); - - const data = await (await this.request(uri.href)).json(); - // API rate limit - await wait(250); - - mangaList = [...mangaList, ...data.data]; - } - - for (let i = 0; i < mangaList.length; i++) { - const manga = mangaList[i]; - const attributes = manga.attributes; - const relationships = manga.relationships; - - const title = attributes.title["en"] ?? attributes.title["ja"] ?? attributes.title["ja-ro"] ?? attributes.title["ko"]; - - const altTitles: string[] = []; - - attributes.altTitles.map((element: { [key: string]: string }, index: number) => { - const temp = element; - if (temp["ja-ro"] != undefined) { - altTitles.push(temp["ja-ro"]); - } - if (temp["ja"] != undefined) { - altTitles.push(temp["ja"]); - } - if (temp["ko"] != undefined) { - altTitles.push(temp["ko"]); - } - if (temp["en"] != undefined) { - altTitles.push(temp["en"]); - } - }); - - const id = manga.id; - let img = ""; - relationships.map((element: { id: string; type: string; related: string; attributes: { [key: string]: string } }) => { - if (element.type === "cover_art") { - img = `${this.url}/covers/${id}/${element.id}.jpg.512.jpg`; - } - }); - - const formatString: string = manga.type.toUpperCase(); - const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; - - results.push({ - id, - title: title, - altTitles: altTitles, - img: img, - format, - year: attributes.year, - providerId: this.id, - }); - } - return results; - } - - override async fetchChapters(id: string): Promise { - const chapterList: Chapter[] = []; - - for (let page = 0, run = true; run; page++) { - const request = await this.request(`${this.api}/manga/${id}/feed?limit=500&translatedLanguage%5B%5D=en&includes[]=scanlation_group&includes[]=user&order[volume]=desc&order[chapter]=desc&offset=${500 * page}&contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic`).catch((err) => { - return null; - }); - if (!request) { - run = false; - break; - } - - await wait(250); - - const data = await request.json(); - - if (!data || !data.result) { - run = false; - break; - } - - if (data.result === "error") { - const error = data.errors[0]; - throw new Error(error.detail); - } - - const chapters: Chapter[] = []; - Object.keys(data.data).map((chapter) => { - const curChapter = data.data[chapter]; - const id = curChapter.id; - let title = ""; - - if (curChapter.attributes.volume) { - title += "Vol. " + this.padNum(curChapter.attributes.volume, 2) + " "; - } - if (curChapter.attributes.chapter) { - title += "Ch. " + this.padNum(curChapter.attributes.chapter, 2) + " "; - } - - let canPush = true; - for (let i = 0; i < chapters.length; i++) { - if (chapters[i].title === title) { - canPush = false; - } - } - - if (canPush) { - chapters.push({ - id, - title: title?.trim(), - number: curChapter.attributes.chapter, - updatedAt: new Date(curChapter.attributes.updatedAt ?? 0).getTime(), - }); - } - }); - - chapters.length > 0 ? chapterList.push(...chapters) : (run = false); - } - - return chapterList; - } - - override async fetchPages(id: string): Promise { - const req = await this.request(`${this.api}/at-home/server/${id}`).catch((err) => { - return null; - }); - - if (!req) { - return []; - } - - await wait(250); - - const data = await req.json(); - - const baseUrl = data.baseUrl; - const hash = data.chapter.hash; - - const pages: Page[] = []; - for (let i = 0; i < data.chapter.data.length; i++) { - const url = `${baseUrl}/data/${hash}/${data.chapter.data[i]}`; - pages.push({ - url: url, - index: i, - headers: { - Referer: this.url, - }, - }); - } - return pages; - } -} diff --git a/anify-backend/src/mapping/impl/manga/mangafox.ts b/anify-backend/src/mapping/impl/manga/mangafox.ts deleted file mode 100644 index 74642c3..0000000 --- a/anify-backend/src/mapping/impl/manga/mangafox.ts +++ /dev/null @@ -1,97 +0,0 @@ -import MangaProvider, { Chapter, Page } from "."; -import { Format, Result } from "../.."; -import { load } from "cheerio"; - -export default class MangaFox extends MangaProvider { - override rateLimit = 250; - override id = "mangafox"; - override url = "https://fanfox.net"; - - override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - // &genres=&nogenres=&sort=&stype=1&name=&type=0&author_method=cw&author=&artist_method=cw&artist=&rating_method=eq&rating=&released_method=eq&released=&st=0 - const data = await (await this.request(`${this.url}/search?title=${encodeURIComponent(query)}&genres=${format === Format.ONE_SHOT ? "26" : ""}&nogenres=&sort=&stype=1&name=&type=0&author_method=cw&author=&artist_method=cw&artist=&rating_method=eq&rating=&released_method=eq&released=${year && year != 0 ? year : ""}&st=0`)).text(); - const $ = load(data); - - $("ul.manga-list-4-list li").map((i, el) => { - const title = $(el).find("a").attr("title"); - const img = $(el).find("img").attr("src"); - - results.push({ - id: $(el).find("a").attr("href") ?? "", - altTitles: [], - format: Format.UNKNOWN, - img: img ?? "", - providerId: this.id, - title: title ?? "", - year: 0, - }); - }); - - return results; - } - - override async fetchChapters(id: string): Promise { - const results: Chapter[] = []; - - const data = await (await this.request(`${this.url}${id}`)).text(); - - const $ = load(data); - $("div#list-1 ul.detail-main-list li").map((i, el) => { - let title = $(el).find("a").attr("title"); - if (title?.includes(" - ")) { - title = title.split(" - ")[0]; - } - - let volume = -1.0; - let chapter = -1.0; - - if (title?.includes("Vol.") && title.includes("Ch.")) { - volume = Number(title.split("Vol.")[1].split("Ch.")[0].trim()); - chapter = Number(title.split("Vol.")[1].split("Ch.")[1].trim()); - } else if (title?.includes("Vol.")) { - volume = Number(title.split("Vol.")[1].trim()); - } else if (title?.includes("Ch.")) { - chapter = Number(title.split("Ch.")[1].trim()); - } - - results.push({ - id: $(el).find("a").attr("href")?.replace("/manga/", "")?.replace("/1.html", "") ?? "", - number: chapter != -1.0 ? chapter : i, - title: title ?? "", - updatedAt: new Date($(el).find("a p.title2").text()).getTime(), - }); - }); - - return results; - } - - override async fetchPages(id: string): Promise { - const pages: Page[] = []; - - const data = await ( - await this.request(`https://m.fanfox.net/roll_manga/${id}/1.html`, { - headers: { - Cookie: "readway=2", - }, - }) - ).text(); - - const $ = load(data); - - $("div#viewer img").map((i, el) => { - pages.push({ - url: $(el).attr("data-original")?.startsWith("//") ? `https:${$(el).attr("data-original")}` : $(el).attr("data-original") ?? "", - index: i, - headers: { - Referer: "https://m.fanfox.net", - }, - }); - }); - - return pages; - } -} diff --git a/anify-backend/src/mapping/impl/manga/mangasee.ts b/anify-backend/src/mapping/impl/manga/mangasee.ts deleted file mode 100644 index 68a476f..0000000 --- a/anify-backend/src/mapping/impl/manga/mangasee.ts +++ /dev/null @@ -1,127 +0,0 @@ -import MangaProvider, { Chapter, Page } from "."; -import { Format, Result } from "../.."; -import { stringSearch } from "../../../helper"; -import { load } from "cheerio"; - -export default class MangaSee extends MangaProvider { - override rateLimit = 250; - override id = "mangasee"; - override url = "https://mangasee123.com"; - - override formats: Format[] = [Format.MANGA, Format.ONE_SHOT]; - - override async search(query: string, format?: Format, year?: number): Promise { - const list = await this.getMangaList(); - const results: Result[] = []; - - for (let i = 0; i < list.length; i++) { - if (stringSearch(list[i].s, query) >= 1) { - results.push({ - title: list[i].s, - id: `/manga/${list[i].i}`, - altTitles: list[i].a, - year: 0, - img: null, - format: Format.UNKNOWN, - providerId: this.id, - }); - } - } - return results; - } - - override async fetchChapters(id: string): Promise { - const data = await this.request(`${this.url}${id}`); - const chapters: Chapter[] = []; - - const $ = load(await data.text()); - - const mangaId = id.split("/manga/")[1]; - const contentScript = $("body > script:nth-child(16)").get()[0].children[0] as any; - - const chaptersData = this.processScriptTagVariable(contentScript["data"], "vm.Chapters = "); - chaptersData?.map((i: { [x: string]: any }) => { - chapters.push({ - id: `/read-online/${mangaId}-chapter-${this.processChapterNumber(i["Chapter"])}`, - title: `${i["ChapterName"] && i["ChapterName"].length > 0 ? i["ChapterName"] : `Chapter ${this.processChapterNumber(i["Chapter"])}`}`, - number: parseInt(this.processChapterNumber(i["Chapter"])), - updatedAt: new Date(i["Date"]).getTime(), - }); - }); - - return chapters; - } - - override async fetchPages(id: string): Promise { - const data = await this.request(`${this.url}${id}-page-1.html`); - - const images: Page[] = []; - - const $ = load(await data.text()); - - const chapterScript = $("body > script:nth-child(19)").get()[0].children[0] as any; - const curChapter = this.processScriptTagVariable(chapterScript["data"], "vm.CurChapter = "); - const imageHost = this.processScriptTagVariable(chapterScript["data"], "vm.CurPathName = "); - const curChapterLength = Number(curChapter["Page"]); - - for (let i = 0; i < curChapterLength; i++) { - const chapter = this.processChapterForImageUrl(id.replace(/[^0-9.]/g, "")); - const page = `${i + 1}`.padStart(3, "0"); - const mangaId = id.split("-chapter-", 1)[0].split("/read-online/")[1]; - const imagePath = `https://${imageHost}/manga/${mangaId}/${chapter}-${page}.png`; - - images.push({ - url: imagePath, - index: i, - headers: { - Referer: this.url, - }, - }); - } - - return images; - } - - private processScriptTagVariable = (script: string, variable: string) => { - const chopFront = script.substring(script.search(variable) + variable.length, script.length); - const chapters = JSON.parse(chopFront.substring(0, chopFront.search(";"))); - - return chapters; - }; - - private processChapterNumber = (chapter: string): string => { - const decimal = chapter.substring(chapter.length - 1, chapter.length); - chapter = chapter.replace(chapter[0], "").slice(0, -1); - if (decimal == "0") return `${+chapter}`; - - if (chapter.startsWith("0")) chapter = chapter.replace(chapter[0], ""); - - return `${+chapter}.${decimal}`; - }; - - private processChapterForImageUrl = (chapter: string): string => { - if (!chapter.includes(".")) return chapter.padStart(4, "0"); - - const values = chapter.split("."); - const pad = values[0].padStart(4, "0"); - - return `${pad}.${values[1]}`; - }; - - private async getMangaList(): Promise { - const req = await this.request(`${this.url}/_search.php`, { - method: "POST", - headers: { - Referer: this.url, - }, - }); - const data: [SearchResult] = await req.json(); - return data; - } -} - -interface SearchResult { - i: string; // image - s: string; // Main title - a: [string]; // Alternative titles -} diff --git a/anify-backend/src/mapping/impl/manga/novelbuddy.ts b/anify-backend/src/mapping/impl/manga/novelbuddy.ts deleted file mode 100644 index 9cad6a0..0000000 --- a/anify-backend/src/mapping/impl/manga/novelbuddy.ts +++ /dev/null @@ -1,70 +0,0 @@ -import MangaProvider, { Chapter, Page } from "."; -import { Format, Result } from "../.."; -import { load } from "cheerio"; - -export default class NovelBuddy extends MangaProvider { - override rateLimit = 250; - override id = "novelbuddy"; - override url = "https://novelbuddy.com"; - - override formats: Format[] = [Format.NOVEL]; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - // Replace non-text or number characters. For example () and []. - const data = await (await this.request(`${this.url}/search?q=${encodeURIComponent(query)}`)).text(); - - const $ = load(data); - - $("div.container div.manga-list div.book-item").map((i, el) => { - const url = `${$(el).find("a").attr("href")}`; - const title = $(el).find("a").attr("title"); - const img = `https:${$(el).find("img").attr("data-src")}`; - - results.push({ - id: url, - title: title?.trim()!, - img: img, - year: 0, - format: Format.NOVEL, - altTitles: [], - providerId: this.id, - }); - }); - - return results; - } - - override async fetchChapters(id: string): Promise { - const chapters: Chapter[] = []; - - const data = await (await this.request(`${this.url}${id}`)).text(); - - const $ = load(data); - - $("ul.chapter-list li").map((i, el) => { - const url = $(el).find("a").attr("href"); - const title = $(el).find("a").attr("title"); - const number = $(el).attr("id")?.split("c-")[1]!; - const updatedAt = new Date($(el).find("time").text() ?? 0).getTime(); - - chapters.push({ - id: url!, - title: title!, - number: parseInt(number), - updatedAt, - }); - }); - - return chapters; - } - - override async fetchPages(id: string): Promise { - const req = await this.request(`${this.url}${id}`); - - const $ = load(await req.text()); - - return $("div.content-inner").html()!; - } -} diff --git a/anify-backend/src/mapping/impl/manga/novelupdates.ts b/anify-backend/src/mapping/impl/manga/novelupdates.ts deleted file mode 100644 index 75daba3..0000000 --- a/anify-backend/src/mapping/impl/manga/novelupdates.ts +++ /dev/null @@ -1,119 +0,0 @@ -import MangaProvider, { Chapter, Page } from "."; -import { Format, Result } from "../.."; -import { load } from "cheerio"; -import { extract } from "@extractus/article-extractor"; - -export default class NovelUpdates extends MangaProvider { - override rateLimit = 1000; - override id = "novelupdates"; - override url = "https://www.novelupdates.com"; - - override formats: Format[] = [Format.NOVEL]; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - const searchData = await this.request( - `${this.url}/series-finder/?sf=1&sh=${encodeURIComponent(query)}&nt=2443,26874,2444&ge=280&sort=sread&order=desc`, - { - method: "GET", - headers: { - Referer: this.url, - }, - }, - true - ); - - const data = await searchData.text(); - - const $ = load(data); - - $("div.search_main_box_nu").each((_, el) => { - const img = $(el).find("div.search_img_nu img").attr("src"); - const title = $(el).find("div.search_body_nu div.search_title a").text(); - const id = $(el).find("div.search_body_nu div.search_title a").attr("href")?.split(this.url)[1]; - - results.push({ - id: id!, - title: title!, - img: img!, - altTitles: [], - format: Format.NOVEL, - providerId: this.id, - year: 0, - }); - }); - - return results; - } - - override async fetchChapters(id: string): Promise { - const chapters: Chapter[] = []; - - const data = await ( - await this.request( - `${this.url}${id}`, - { - headers: { - Cookie: "_ga=;", - }, - }, - true - ) - ).text(); - - const $ = load(data); - - const postId = $("input#mypostid").attr("value"); - - const chapterData = ( - await ( - await this.request( - `${this.url}/wp-admin/admin-ajax.php`, - { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", - Cookie: "_ga=;", - }, - body: `action=nd_getchapters&mypostid=${postId}&mypostid2=0`, - }, - true - ) - ).text() - ).substring(1); - - const $$ = load(chapterData); - $$("li.sp_li_chp a[data-id]").each((index, el) => { - const id = $$(el).attr("data-id"); - const title = $$(el).find("span").text(); - - chapters.push({ - id: id!, - title: title!, - number: index + 1, - }); - }); - - return chapters; - } - - override async fetchPages(id: string): Promise { - const data = await ( - await this.request( - `${this.url}/extnu/${id}/`, - { - method: "GET", - headers: { - Cookie: "_ga=;", - }, - redirect: "follow", - }, - true - ) - ).text(); - - const article = await extract(data); - return article?.content; - } -} diff --git a/anify-backend/src/mapping/impl/manga/readlightnovels.ts b/anify-backend/src/mapping/impl/manga/readlightnovels.ts deleted file mode 100644 index d2ee3d0..0000000 --- a/anify-backend/src/mapping/impl/manga/readlightnovels.ts +++ /dev/null @@ -1,104 +0,0 @@ -import MangaProvider, { Chapter, Page } from "."; -import { Format, Result } from "../.."; -import { load } from "cheerio"; - -export default class ReadLightNovels extends MangaProvider { - override rateLimit = 250; - override id = "readlightnovels"; - override url = "https://readlightnovels.net"; - - override formats: Format[] = [Format.NOVEL]; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - const data = await ( - await this.request(`${this.url}/?s=${encodeURIComponent(query)}`, { - method: "POST", - }) - ).text(); - - const $ = load(data); - - $("div.col-xs-12.col-sm-12.col-md-9.col-truyen-main > div:nth-child(1) > div > div:nth-child(2) > div.col-md-3.col-sm-6.col-xs-6.home-truyendecu").each((i, el) => { - results.push({ - id: $(el).find("a").attr("href")!.split(this.url)[1], - title: $(el).find("a").attr("title")!, - altTitles: [], - img: $(el).find("a > img").attr("src")!, - year: 0, - format: Format.NOVEL, - providerId: this.id, - }); - }); - - return results; - } - - override async fetchChapters(id: string): Promise { - id = id.replace(".html", ""); - - const chapters: Chapter[] = []; - - const data = await ( - await this.request(`${this.url}${id}.html`, { - headers: { - Referer: `${this.url}${id}.html`, - }, - }) - ).text(); - - const $ = load(data); - - const pages = - Math.max( - ...$("#pagination > ul > li") - .map((i, el) => parseInt($(el).find("a").attr("data-page")!)) - .get() - .filter((x) => !isNaN(x)) - ) != -Infinity - ? Math.max( - ...$("#pagination > ul > li") - .map((i, el) => parseInt($(el).find("a").attr("data-page")!)) - .get() - .filter((x) => !isNaN(x)) - ) - : 0; - - const novelId = parseInt($("#id_post").val() as string); - - const bodyFormData = new FormData(); - bodyFormData.append("action", "tw_ajax"); - bodyFormData.append("type", "pagination"); - bodyFormData.append("page", String(pages)); - bodyFormData.append("id", String(novelId)); - - for (const chapter of $("ul.list-chapter > li")) { - const subId = $(chapter).find("a").attr("href")!.split("/")?.pop()!.replace(".html", "")!; - const id = $(chapter).find("a").attr("href")!.split("/")[3]; - chapters.push({ - id: `/${id}/${subId}`, - title: $(chapter).find("a > span").text().trim(), - number: parseFloat($(chapter).find("a > span").text().trim().split(" ")[1]), - }); - } - - return chapters; - } - - override async fetchPages(id: string): Promise { - const data = await (await this.request(`${this.url}${id}.html`)).text(); - - const $ = load(data); - - let contents = ""; - - for (const line of $("div.chapter-content > p")) { - if ($(line).text() != "") { - contents += `${$(line).text()}\n`; - } - } - - return contents; - } -} diff --git a/anify-backend/src/mapping/impl/manga/vynovel.ts b/anify-backend/src/mapping/impl/manga/vynovel.ts deleted file mode 100644 index c50242d..0000000 --- a/anify-backend/src/mapping/impl/manga/vynovel.ts +++ /dev/null @@ -1,66 +0,0 @@ -import MangaProvider, { Chapter, Page } from "."; -import { Format, Result } from "../.."; -import { load } from "cheerio"; - -export default class VyNovel extends MangaProvider { - override rateLimit = 250; - override id = "vynovel"; - override url = "https://vynovel.com"; - - override formats: Format[] = [Format.NOVEL]; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - const data = await ( - await this.request(`${this.url}/api/manga/search?search=${encodeURIComponent(query)}&uid=`, { - headers: { - "X-Requested-With": "XMLHttpRequest", - }, - }) - ).json(); - - for (const res of data.result) { - results.push({ - id: res.name_url, - title: res.name, - altTitles: res.title ? [res.title] : [], - format: Format.UNKNOWN, - img: res.thumbnail, - providerId: this.id, - year: 0, - }); - } - - return results; - } - - override async fetchChapters(id: string): Promise { - const chapters: Chapter[] = []; - - const data = await (await this.request(`${this.url}/novel/${id}`)).text(); - - const $ = load(data); - - $("div.div-chapter div.list-group a").map((i, el) => { - const id = $(el).attr("href")?.split(this.url)[1]; - const title = $(el).find("span").text(); - chapters.push({ - id: id ?? "", - title: title?.trim(), - number: i + 1, - updatedAt: new Date($(el).find("p").text()).getTime(), - }); - }); - - return chapters; - } - - override async fetchPages(id: string): Promise { - const data = await (await this.request(`${this.url}${id}`)).text(); - - const $ = load(data); - - return $("div#content-reader div.content").text() ?? "Error fetching content!"; - } -} diff --git a/anify-backend/src/mapping/impl/meta/index.ts b/anify-backend/src/mapping/impl/meta/index.ts deleted file mode 100644 index c472c67..0000000 --- a/anify-backend/src/mapping/impl/meta/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Format, ProviderType, Result } from "../.."; -import Http from "../request"; - -export default abstract class MetaProvider { - abstract rateLimit: number; - abstract id: string; - abstract url: string; - abstract formats: Format[]; - - public providerType: ProviderType = ProviderType.META; - public customProxy: string | undefined; - - async search(query: string, format?: Format, year?: number): Promise { - return undefined; - } - - async request(url: string, config: RequestInit = {}, proxyRequest = false): Promise { - return Http.request(url, config, proxyRequest, 0, this.customProxy); - } -} diff --git a/anify-backend/src/mapping/impl/meta/kitsuanime.ts b/anify-backend/src/mapping/impl/meta/kitsuanime.ts deleted file mode 100644 index aae5b20..0000000 --- a/anify-backend/src/mapping/impl/meta/kitsuanime.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { Format, Formats, Result, Type } from "../.."; -import MetaProvider from "."; - -export default class KitsuAnime extends MetaProvider { - override rateLimit = 250; - override id = "kitsu"; - override url = "https://kitsu.io"; - override formats: Format[] = [Format.TV, Format.MOVIE, Format.ONA, Format.SPECIAL, Format.TV_SHORT, Format.OVA]; - - private kitsuApiUrl = "https://kitsu.io/api/edge"; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - const searchUrl = `/anime?filter[text]=${encodeURIComponent(query)}`; - const req = await this.request( - this.kitsuApiUrl + searchUrl, - { - headers: { - Accept: "application/vnd.api+json", - "Content-Type": "application/vnd.api+json", - }, - }, - true - ).catch((err) => { - return null; - }); - if (!req) { - return results; - } - const data = await req.json(); - if (data.data.length > 0) { - data.data.forEach((result: KitsuResult) => { - const altTitles = [result.attributes.titles.en_jp, result.attributes.titles.ja_jp, result.attributes.titles.en_us, result.attributes.titles.en, result.attributes.titles.en_kr, result.attributes.titles.ko_kr, result.attributes.titles.en_cn, result.attributes.titles.zh_cn].filter(Boolean); - - const formatString = result.attributes.subtype.toUpperCase(); - const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; - - results.push({ - title: result.attributes.titles.en_us || result.attributes.titles.en_jp || result.attributes.titles.ja_jp || result.attributes.titles.en || result.attributes.titles.en_kr || result.attributes.titles.ko_kr || result.attributes.titles.en_cn || result.attributes.titles.zh_cn || result.attributes.canonicalTitle || result.attributes.slug, - altTitles: altTitles, - id: result.id, - img: result.attributes.posterImage?.original ?? null, - format, - year: result.attributes.startDate ? new Date(result.attributes.startDate).getFullYear() : 0, - providerId: this.id, - }); - }); - return results; - } else { - return results; - } - } -} - -type KitsuResult = { - id: string; - type: string; - links: { - self: string; - }; - attributes: { - createdAt: string; - updatedAt: string; - slug: string; - synopsis: string; - description: string; - coverImageTopOffset: number; - titles: { - en: string; - en_us: string; - en_kr: string; - en_cn: string; - en_jp: string; - fr_fr: string; - ja_jp: string; - ko_kr: string; - pt_pt: string; - ru_ru: string; - th_th: string; - zh_cn: string; - }; - canonicalTitle: string; - abbreviatedTitles: string[]; - averageRating: string; - ratingFrequencies: { - [key: string]: string; - }; - userCount: number; - favoritesCount: number; - startDate: string; - endDate: string | null; - nextRelease: string | null; - popularityRank: number; - ratingRank: number; - ageRating: string; - ageRatingGuide: string | null; - subtype: string; - status: string; - tba: string | null; - posterImage: { - tiny: string; - large: string; - small: string; - medium: string; - original: string; - meta: { - dimensions: { - tiny: { - width: number; - height: number; - }; - large: { - width: number; - height: number; - }; - small: { - width: number; - height: number; - }; - medium: { - width: number; - height: number; - }; - }; - }; - }; - coverImage: { - tiny: string; - large: string; - small: string; - original: string; - meta: { - dimensions: { - tiny: { - width: number; - height: number; - }; - large: { - width: number; - height: number; - }; - small: { - width: number; - height: number; - }; - }; - }; - }; - chapterCount: number | null; - volumeCount: number | null; - serialization: string; - mangaType: string; - }; - relationships: { - genres: { - links: { - self: string; - related: string; - }; - }; - categories: { - links: { - self: string; - related: string; - }; - }; - castings: { - links: { - self: string; - related: string; - }; - }; - installments: { - links: { - self: string; - related: string; - }; - }; - mappings: { - links: { - self: string; - related: string; - }; - }; - reviews: { - links: { - self: string; - related: string; - }; - }; - mediaRelationships: { - links: { - self: string; - related: string; - }; - }; - characters: { - links: { - self: string; - related: string; - }; - }; - staff: { - links: { - self: string; - related: string; - }; - }; - productions: { - links: { - self: string; - related: string; - }; - }; - quotes: { - links: { - self: string; - related: string; - }; - }; - chapters: { - links: { - self: string; - related: string; - }; - }; - mangaCharacters: { - links: { - self: string; - related: string; - }; - }; - mangaStaff: { - links: { - self: string; - related: string; - }; - }; - }; -}; diff --git a/anify-backend/src/mapping/impl/meta/kitsumanga.ts b/anify-backend/src/mapping/impl/meta/kitsumanga.ts deleted file mode 100644 index b56a944..0000000 --- a/anify-backend/src/mapping/impl/meta/kitsumanga.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { Format, Formats, Result, Type } from "../.."; -import MetaProvider from "."; - -export default class KitsuManga extends MetaProvider { - override rateLimit = 250; - override id = "kitsu"; - override url = "https://kitsu.io"; - override formats: Format[] = [Format.MANGA, Format.ONE_SHOT, Format.NOVEL]; - - private kitsuApiUrl = "https://kitsu.io/api/edge"; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - const searchUrl = `/manga?filter[text]=${encodeURIComponent(query)}`; - const req = await this.request( - this.kitsuApiUrl + searchUrl, - { - headers: { - Accept: "application/vnd.api+json", - "Content-Type": "application/vnd.api+json", - }, - }, - true - ).catch((err) => { - return null; - }); - if (!req) { - return results; - } - const data = await req.json(); - if (data.data.length > 0) { - data.data.forEach((result: KitsuResult) => { - const altTitles = [result.attributes.titles.en_jp, result.attributes.titles.ja_jp, result.attributes.titles.en_us, result.attributes.titles.en, result.attributes.titles.en_kr, result.attributes.titles.ko_kr, result.attributes.titles.en_cn, result.attributes.titles.zh_cn].filter(Boolean); - - const formatString = result.attributes.subtype.toUpperCase(); - const format: Format = Formats.includes(formatString as Format) ? (formatString as Format) : Format.UNKNOWN; - - results.push({ - title: result.attributes.titles.en_us || result.attributes.titles.en_jp || result.attributes.titles.ja_jp || result.attributes.titles.en || result.attributes.titles.en_kr || result.attributes.titles.ko_kr || result.attributes.titles.en_cn || result.attributes.titles.zh_cn || result.attributes.canonicalTitle || result.attributes.slug, - altTitles: altTitles, - id: result.id, - img: result.attributes.posterImage?.original ?? null, - format, - year: result.attributes.startDate ? new Date(result.attributes.startDate).getFullYear() : 0, - providerId: this.id, - }); - }); - return results; - } else { - return results; - } - } -} - -type KitsuResult = { - id: string; - type: string; - links: { - self: string; - }; - attributes: { - createdAt: string; - updatedAt: string; - slug: string; - synopsis: string; - description: string; - coverImageTopOffset: number; - titles: { - en: string; - en_us: string; - en_kr: string; - en_cn: string; - en_jp: string; - fr_fr: string; - ja_jp: string; - ko_kr: string; - pt_pt: string; - ru_ru: string; - th_th: string; - zh_cn: string; - }; - canonicalTitle: string; - abbreviatedTitles: string[]; - averageRating: string; - ratingFrequencies: { - [key: string]: string; - }; - userCount: number; - favoritesCount: number; - startDate: string; - endDate: string | null; - nextRelease: string | null; - popularityRank: number; - ratingRank: number; - ageRating: string; - ageRatingGuide: string | null; - subtype: string; - status: string; - tba: string | null; - posterImage: { - tiny: string; - large: string; - small: string; - medium: string; - original: string; - meta: { - dimensions: { - tiny: { - width: number; - height: number; - }; - large: { - width: number; - height: number; - }; - small: { - width: number; - height: number; - }; - medium: { - width: number; - height: number; - }; - }; - }; - }; - coverImage: { - tiny: string; - large: string; - small: string; - original: string; - meta: { - dimensions: { - tiny: { - width: number; - height: number; - }; - large: { - width: number; - height: number; - }; - small: { - width: number; - height: number; - }; - }; - }; - }; - chapterCount: number | null; - volumeCount: number | null; - serialization: string; - mangaType: string; - }; - relationships: { - genres: { - links: { - self: string; - related: string; - }; - }; - categories: { - links: { - self: string; - related: string; - }; - }; - castings: { - links: { - self: string; - related: string; - }; - }; - installments: { - links: { - self: string; - related: string; - }; - }; - mappings: { - links: { - self: string; - related: string; - }; - }; - reviews: { - links: { - self: string; - related: string; - }; - }; - mediaRelationships: { - links: { - self: string; - related: string; - }; - }; - characters: { - links: { - self: string; - related: string; - }; - }; - staff: { - links: { - self: string; - related: string; - }; - }; - productions: { - links: { - self: string; - related: string; - }; - }; - quotes: { - links: { - self: string; - related: string; - }; - }; - chapters: { - links: { - self: string; - related: string; - }; - }; - mangaCharacters: { - links: { - self: string; - related: string; - }; - }; - mangaStaff: { - links: { - self: string; - related: string; - }; - }; - }; -}; diff --git a/anify-backend/src/mapping/impl/meta/simkl.ts b/anify-backend/src/mapping/impl/meta/simkl.ts deleted file mode 100644 index 77b88d8..0000000 --- a/anify-backend/src/mapping/impl/meta/simkl.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Format, Result } from "../.."; -import MetaProvider from "."; -import { env } from "../../../env"; - -export default class SimklMeta extends MetaProvider { - override rateLimit = 250; - override id = "simkl"; - override url = "https://simkl.com"; - override formats: Format[] = [Format.TV, Format.MOVIE, Format.ONA, Format.SPECIAL, Format.TV_SHORT, Format.OVA]; - - private simklKey = env.SIMKL_CLIENT_SECRET ?? ""; - private simklClient = env.SIMKL_CLIENT_ID ?? ""; - private simklApiUrl = "https://api.simkl.com"; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - const req = await this.request(`${this.simklApiUrl}/search/anime?q=${query}&client_id=${this.simklClient}`, { - headers: { - "Content-Type": "application/json", - "X-Pagination-Page": "1", - "X-Pagination-Page-Count": "10", - "X-Pagination-Item-Count": "50", - }, - }); - - const data: SearchResponse[] = await req.json(); - - if (!Array.isArray(data)) { - return undefined; - } - - for (const item of data) { - const altTitles: string[] = []; - - if (item.title_en) altTitles.push(item.title_en); - if (item.title_romaji) altTitles.push(item.title_romaji); - - results.push({ - id: item.ids.simkl_id.toString(), - title: item.title, - altTitles: altTitles, - format: Format.UNKNOWN, - img: `${this.url}/posters/${item.poster}_m.jpg`, - year: item.year ?? 0, - providerId: this.id, - }); - } - - return results; - } -} - -interface SearchResponse { - title: string; - title_en?: string; - title_romaji?: string; - year: number; - poster: string; - ids: { - simkl_id: number; - slug: string; - tmdb: string; - }; -} diff --git a/anify-backend/src/mapping/impl/meta/tmdb.ts b/anify-backend/src/mapping/impl/meta/tmdb.ts deleted file mode 100644 index eac3d53..0000000 --- a/anify-backend/src/mapping/impl/meta/tmdb.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { Format, Result } from "../.."; -import MetaProvider from "."; - -export default class TMDB extends MetaProvider { - override rateLimit = 500; - override id = "tmdb"; - override url = "https://themoviedb.org"; - override formats: Format[] = [Format.TV, Format.MOVIE, Format.ONA, Format.SPECIAL, Format.TV_SHORT, Format.OVA]; - - private tmdbApiUrl = "https://api.themoviedb.org/3"; - private apiKey = "5201b54eb0968700e693a30576d7d4dc"; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - const page = 1; - const searchUrl = `/search/multi?api_key=${this.apiKey}&language=en-US&page=${page}&include_adult=false&query=${encodeURIComponent(query)}`; - - const data = await (await this.request(this.tmdbApiUrl + searchUrl)).json(); - - if (!data) return undefined; - - if (data.results.length > 0) { - data.results.forEach((result: TMDBResult) => { - if (result.media_type === "tv") { - results.push({ - id: `/tv/${result.id}`, - title: result.title || result.name, - altTitles: [result.original_title || result.original_name, result.title || result.name], - img: `https://image.tmdb.org/t/p/w500${result.poster_path}`, - format: Format.UNKNOWN, - year: result.first_air_date ? new Date(result.first_air_date).getFullYear() : 0, - providerId: this.id, - }); - } else if (result.media_type === "movie") { - results.push({ - id: `/movie/${result.id}`, - title: result.title || result.name, - altTitles: [result.original_title || result.original_name, result.title || result.name], - img: `https://image.tmdb.org/t/p/w500${result.poster_path}`, - format: Format.MOVIE, - year: result.first_air_date ? new Date(result.first_air_date).getFullYear() : 0, - providerId: this.id, - }); - } - }); - return results; - } else { - return results; - } - } - - public async getEpisodeCovers(id: string, seasonNumber: number): Promise<{ episode: number; img: string }[] | undefined> { - const seasonUrl = `${id}/season/${seasonNumber}?api_key=${this.apiKey}`; - const data = await (await this.request(this.tmdbApiUrl + seasonUrl)).json(); - const episodes = data.episodes; - const episodeCovers: { episode: number; img: string }[] = []; - if (!episodes) { - return []; - } - episodes.forEach((episode: Episode) => { - if (episode.still_path != null) { - episodeCovers.push({ - episode: episode.episode_number, - img: `https://image.tmdb.org/t/p/original${episode.still_path}`, - }); - } - }); - return episodeCovers; - } -} - -type TMDBResult = { - adult: boolean; - backdrop_path: string | null; - id: number; - title?: string; - name: string; - original_language: string; - original_title?: string; - original_name: string; - overview: string; - poster_path: string | null; - media_type: string; - genre_ids: number[]; - popularity: number; - first_air_date: string; - vote_average: number; - vote_count: number; - origin_country: string[]; -}; - -type Episode = { - air_date: string; - episode_number: number; - episode_type: string; - id: number; - name: string; - overview: string; - production_code: string; - runtime: number; - season_number: number; - show_id: number; - still_path: string; - vote_average: number; - vote_count: number; - crew: { - job: string; - department: string; - credit_id: string; - adult: boolean; - gender: number; - id: number; - known_for_department: string; - name: string; - original_name: string; - popularity: number; - profile_path: string | null; - }[]; - guest_stars: { - character: string; - credit_id: string; - order: number; - adult: boolean; - gender: number; - id: number; - known_for_department: string; - name: string; - original_name: string; - popularity: number; - profile_path: string | null; - }[]; -}; diff --git a/anify-backend/src/mapping/impl/meta/tvdb.ts b/anify-backend/src/mapping/impl/meta/tvdb.ts deleted file mode 100644 index 844a503..0000000 --- a/anify-backend/src/mapping/impl/meta/tvdb.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { Format, Result } from "../.."; -import MetaProvider from "."; - -export default class TheTVDB extends MetaProvider { - override rateLimit = 500; - override id = "tvdb"; - override url = "https://thetvdb.com"; - override formats: Format[] = [Format.TV, Format.MOVIE, Format.ONA, Format.SPECIAL, Format.TV_SHORT, Format.OVA]; - - private tvdbApiUrl = "https://api4.thetvdb.com/v4"; - - private apiKeys = ["f5744a13-9203-4d02-b951-fbd7352c1657", "8f406bec-6ddb-45e7-8f4b-e1861e10f1bb", "5476e702-85aa-45fd-a8da-e74df3840baf", "51020266-18f7-4382-81fc-75a4014fa59f"]; - - override async search(query: string, format?: Format, year?: number): Promise { - const results: Result[] = []; - - const isSeason = query.toLowerCase().includes("season"); - - if (isSeason) { - query = query.toLowerCase().replace("season", ""); - } - - const token = await this.getToken(this.apiKeys[Math.floor(Math.random() * this.apiKeys.length)]); - - const formattedType = format === Format.TV || Format.TV_SHORT || Format.SPECIAL ? "series" : format === Format.MOVIE ? "movie" : undefined; - - const data = await this.request( - `${this.tvdbApiUrl}/search?query=${encodeURIComponent(query)}${year && !isSeason ? `&year=${year}` : ""}${formattedType ? `&type=${formattedType}` : ""}`, - { - headers: { - Authorization: `Bearer ${token}`, - }, - }, - false - ); - - if (data?.ok) { - const searchData: Search[] = (await data.json()).data; - for (const data of searchData) { - if (data.primary_type != TVDBType.SERIES && data.primary_type != TVDBType.MOVIE) continue; - if (isSeason) data.year = "0"; - - results.push({ - id: `/${data.primary_type}/${data.tvdb_id}`, - format: Format.UNKNOWN, - title: data.name, - altTitles: data.aliases ?? [], - img: data.image_url, - year: Number(data.year ?? 0) ?? 0, - providerId: this.id, - }); - } - } - - return results; - } - - private async getToken(key: string): Promise { - const data: Response | undefined = await this.request( - `${this.tvdbApiUrl}/login`, - { - body: JSON.stringify({ - apikey: `${key}`, - }), - method: "POST", - headers: { - "Content-Type": "application/json", - }, - }, - false - ).catch((err) => { - console.error(err); - return undefined; - }); - if (!data) return undefined; - - if (data.ok) { - return (await data.json()).data.token as string; - } - - return undefined; - } -} - -/* Search Types */ -interface Search { - objectID: string; - country?: Country; - director?: string; - extended_title?: string; - genres?: Genre[]; - id: string; - image_url: string; - name: string; - overview?: string; - primary_language?: PrimaryLanguage; - primary_type: TVDBType; - status?: Status; - type: TVDBType; - tvdb_id: string; - year?: string; - slug?: string; - overviews?: Overviews; - translations: Overviews; - remote_ids?: RemoteID[]; - thumbnail?: string; - aliases?: string[]; - first_air_time?: Date; - network?: string; - studios?: string[]; -} - -enum Country { - CZE = "cze", - JPN = "jpn", - USA = "usa", -} - -enum Genre { - ACTION = "Action", - ADVENTURE = "Adventure", - ANIMATION = "Animation", - ANIME = "Anime", - CHILDREN = "Children", - COMEDY = "Comedy", - DRAMA = "Drama", - FAMILY = "Family", - FANTASY = "Fantasy", - SPORT = "Sport", -} - -interface Overviews { - eng?: string; - fra?: string; - ita?: string; - jpn?: string; - pol?: string; - pt?: string; - spa?: string; - por?: string; - ara?: string; - cat?: string; - deu?: string; - heb?: string; - kor?: string; - msa?: string; - rus?: string; - srp?: string; - tur?: string; - zho?: string; - hun?: string; - cha?: string; - nld?: string; - tha?: string; - ces?: string; -} - -enum PrimaryLanguage { - CES = "ces", - ENG = "eng", - ITA = "ita", - JPN = "jpn", -} - -enum TVDBType { - LIST = "list", - MOVIE = "movie", - SERIES = "series", -} - -interface RemoteID { - id: string; - type: number; - sourceName: SourceName; -} - -enum SourceName { - EIDR = "EIDR", - FACEBOOK = "Facebook", - FANSITE = "Fan Site", - IMDB = "IMDB", - INSTAGRAM = "Instagram", - OFFICIAL_WEBSITE = "Official Website", - TMS_ZAP2It = "TMS (Zap2It)", - TMDB = "TheMovieDB.com", - TWITTER = "Twitter", - YOUTUBE = "Youtube", -} - -enum Status { - CONTINUING = "Continuing", - ENDED = "Ended", - RELEASED = "Released", - UPCOMING = "Upcoming", -} diff --git a/anify-backend/src/mapping/impl/request.ts b/anify-backend/src/mapping/impl/request.ts deleted file mode 100644 index fedd918..0000000 --- a/anify-backend/src/mapping/impl/request.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { CORS_PROXIES } from "../../helper/proxies"; -import colors from "colors"; - -export default class Http { - private static bannedProxies: string[] = []; - public static unbannedProxies: string[] = CORS_PROXIES; - - static updateBannedProxies(proxyUrl: string): void { - if (!this.bannedProxies.includes(proxyUrl)) { - this.bannedProxies.push(proxyUrl); - this.unbannedProxies = CORS_PROXIES.filter((proxy) => !this.bannedProxies.includes(proxy)); - } - } - - static getRandomUnbannedProxy(): string | undefined { - if (this.unbannedProxies.length === 0) { - //throw new Error("No unbanned proxies available"); - return undefined; - } - return this.unbannedProxies[Math.floor(Math.random() * this.unbannedProxies.length)]; - } - - static async request(url: string, config: RequestInit = {}, proxyRequest = true, requests = 0, customProxy: string | undefined = undefined): Promise { - try { - if (proxyRequest) { - const proxyUrl = customProxy ? customProxy + "/" : this.getRandomUnbannedProxy() != undefined ? `${this.getRandomUnbannedProxy()}/` : ""; - const modifyUrl = proxyUrl + url; - - const controller = new AbortController(); - const id = setTimeout(() => { - this.updateBannedProxies(proxyUrl); - controller.abort(); - }, 8000); - - try { - config = { - ...config, - headers: { - ...config.headers, - Origin: "https://anify.tv", - }, - }; - const response = await fetch(modifyUrl, { signal: controller.signal, ...config }).catch((err) => { - return { - ok: false, - status: 500, - statusText: "Timeout", - json: () => Promise.resolve({ error: err }), - } as Response; - }); - if (!response.ok) { - this.updateBannedProxies(proxyUrl); - } - - if (response.statusText === "Timeout") { - if (requests >= 3) { - console.log(colors.red("Request timed out. Retried 3 times. Aborting...")); - return response; - } - - return this.request(url, config, proxyRequest, requests + 1); - } - - clearTimeout(id); - return response; - } catch (error) { - console.log(proxyUrl); - clearTimeout(id); - throw error; - } - } else { - return fetch(url, config); - } - } catch (e) { - console.log(e); - return { - ok: false, - status: 500, - statusText: "Internal Server Error", - } as Response; - } - } -} diff --git a/anify-backend/src/mapping/index.ts b/anify-backend/src/mapping/index.ts deleted file mode 100644 index 3b2afb0..0000000 --- a/anify-backend/src/mapping/index.ts +++ /dev/null @@ -1,296 +0,0 @@ -import AnimeProvider from "./impl/anime"; -import InformationProvider, { AnimeInfo, MangaInfo } from "./impl/information"; -import AniList from "./impl/information/anilist"; -import MangaProvider from "./impl/manga"; -import ComicK from "./impl/manga/comicK"; -import MAL from "./impl/information/mal"; -import Kitsu from "./impl/information/kitsu"; -import KitsuAnime from "./impl/meta/kitsuanime"; -import KitsuManga from "./impl/meta/kitsumanga"; -import NineAnime from "./impl/anime/nineanime"; -import GogoAnime from "./impl/anime/gogoanime"; -import Zoro from "./impl/anime/zoro"; -import AnimePahe from "./impl/anime/animepahe"; -import MangaDex from "./impl/manga/mangadex"; -import MangaSee from "./impl/manga/mangasee"; -import MetaProvider from "./impl/meta"; -import NovelBuddy from "./impl/manga/novelbuddy"; -import NovelUpdates from "./impl/manga/novelupdates"; -import TMDB from "./impl/meta/tmdb"; -import JNovels from "./impl/manga/jnovels"; -import ReadLightNovels from "./impl/manga/readlightnovels"; -import { EpisodeData } from "../content/impl/episodes"; -import { ChapterData } from "../content/impl/chapters"; -import TheTVDB from "./impl/meta/tvdb"; -import TVDB from "./impl/information/tvdb"; -import SimklMeta from "./impl/meta/simkl"; -import Simkl from "./impl/information/simkl"; -import Kass from "./impl/anime/kass"; -import ComicKInfo from "./impl/information/comicK"; -import MangaFox from "./impl/manga/mangafox"; -import VyNovel from "./impl/manga/vynovel"; - -const ANIME_PROVIDERS: AnimeProvider[] = [new NineAnime(), new GogoAnime(), new Zoro(), new AnimePahe(), new Kass()]; -const animeProviders: Record = ANIME_PROVIDERS.reduce((acc, provider) => { - acc[provider.id] = provider; - return acc; -}, {} as Record); - -const MANGA_PROVIDERS: MangaProvider[] = [new ComicK(), new MangaDex(), new MangaSee(), new MangaFox(), new NovelBuddy(), new NovelUpdates(), new JNovels(), new ReadLightNovels(), new VyNovel()]; -const mangaProviders: Record = MANGA_PROVIDERS.reduce((acc, provider) => { - acc[provider.id] = provider; - return acc; -}, {} as Record); - -const INFORMATION_PROVIDERS: InformationProvider[] = [new AniList(), new MAL(), new Kitsu(), new TVDB(), new Simkl(), new ComicKInfo()]; -const infoProviders: Record> = INFORMATION_PROVIDERS.reduce((acc, provider) => { - acc[provider.id] = provider; - return acc; -}, {} as Record>); - -const META_PROVIDERS: MetaProvider[] = [new KitsuAnime(), new KitsuManga(), new TMDB(), new TheTVDB(), new SimklMeta()]; -const metaProviders: Record = META_PROVIDERS.reduce((acc, provider) => { - acc[provider.id] = provider; - return acc; -}, {} as Record); - -export { ANIME_PROVIDERS, MANGA_PROVIDERS, INFORMATION_PROVIDERS, META_PROVIDERS, animeProviders, mangaProviders, infoProviders, metaProviders }; - -export type Result = { - id: string; - title: string; - altTitles: string[]; - year: number; - format: Format; - img: string | null; - providerId: string; -}; - -export const enum ProviderType { - ANIME = "ANIME", - MANGA = "MANGA", - META = "META", - INFORMATION = "INFORMATION", -} - -export const enum Type { - ANIME = "ANIME", - MANGA = "MANGA", -} - -export const enum Format { - TV = "TV", - TV_SHORT = "TV_SHORT", - MOVIE = "MOVIE", - SPECIAL = "SPECIAL", - OVA = "OVA", - ONA = "ONA", - MUSIC = "MUSIC", - MANGA = "MANGA", - NOVEL = "NOVEL", - ONE_SHOT = "ONE_SHOT", - UNKNOWN = "UNKNOWN", -} - -export const Formats = [Format.TV, Format.TV_SHORT, Format.MOVIE, Format.SPECIAL, Format.OVA, Format.ONA, Format.MUSIC, Format.MANGA, Format.NOVEL, Format.ONE_SHOT, Format.UNKNOWN]; - -export const enum Season { - WINTER = "WINTER", - SPRING = "SPRING", - SUMMER = "SUMMER", - FALL = "FALL", - UNKNOWN = "UNKNOWN", -} - -export const enum MediaStatus { - FINISHED = "FINISHED", - RELEASING = "RELEASING", - NOT_YET_RELEASED = "NOT_YET_RELEASED", - CANCELLED = "CANCELLED", - HIATUS = "HIATUS", -} - -export const enum Genres { - ACTION = "Action", - ADVENTURE = "Adventure", - ANIME_INFLUENCED = "Anime Influenced", - AVANT_GARDE = "Avant Garde", - AWARD_WINNING = "Award Winning", - BOYS_LOVE = "Boys Love", - CARS = "Cards", - COMEDY = "Comedy", - DEMENTIA = "Dementia", - DEMONS = "Demons", - DOUJINSHI = "Doujinshi", - DRAMA = "Drama", - ECCHI = "Ecchi", - EROTICA = "Erotica", - FAMILY = "Family", - FANTASY = "Fantasy", - FOOD = "Food", - FRIENDSHIP = "Friendship", - GAME = "Game", - GENDER_BENDER = "Gender Bender", - GIRLS_LOVE = "Girls Love", - GORE = "Gore", - GOURMET = "Gourmet", - HAREM = "Harem", - HENTAI = "Hentai", - HISTORICAL = "Historical", - HORROR = "Horror", - ISEKAI = "Isekai", - KIDS = "Kids", - MAGIC = "Magic", - MAHOU_SHOUJO = "Mahou Shoujo", - MARTIAL_ARTS = "Martial Arts", - MECHA = "Mecha", - MEDICAL = "Medical", - MILITARY = "Military", - MUSIC = "Music", - MYSTERY = "Mystery", - PARODY = "Parody", - POLICE = "Police", - POLITICAL = "Political", - PSYCHOLOGICAL = "Psychological", - RACING = "Racing", - ROMANCE = "Romance", - SAMURAI = "Samurai", - SCHOOL = "School", - SCI_FI = "Sci-Fi", - SHOUJO_AI = "Shoujo Ai", - SHOUNEN_AI = "Shounen Ai", - SLICE_OF_LIFE = "Slice of Life", - SPACE = "Space", - SPORTS = "Sports", - SUPER_POWER = "Super Power", - SUPERNATURAL = "Supernatural", - SUSPENCE = "Suspence", - THRILLER = "Thriller", - VAMPIRE = "Vampire", - WORKPLACE = "Workplace", - YAOI = "Yaoi", - YURI = "Yuri", - ZOMBIES = "Zombies", -} - -export type Anime = { - id: string; - slug: string; - coverImage: string | null; - bannerImage: string | null; - trailer: string | null; - status: MediaStatus | null; - season: Season; - title: { - romaji: string | null; - english: string | null; - native: string | null; - }; - currentEpisode: number | null; - mappings: { id: string; providerId: string; similarity: number; providerType: ProviderType | null }[]; - synonyms: string[]; - countryOfOrigin: string | null; - description: string | null; - duration: number | null; - color: string | null; - year: number | null; - rating: { - anilist: number; - mal: number; - kitsu: number; - }; - popularity: { - anilist: number; - mal: number; - kitsu: number; - }; - type: Type; - genres: Genres[]; - format: Format; - relations: Relations[]; - totalEpisodes?: number; - episodes: { - latest: { - updatedAt: number; - latestEpisode: number; - latestTitle: string; - }; - data: EpisodeData[]; - }; - tags: string[]; - artwork: Artwork[]; - characters: Character[]; -}; - -export type Manga = { - id: string; - slug: string; - coverImage: string | null; - bannerImage: string | null; - status: MediaStatus | null; - title: { - romaji: string | null; - english: string | null; - native: string | null; - }; - mappings: { id: string; providerId: string; similarity: number; providerType: ProviderType | null }[]; - synonyms: string[]; - countryOfOrigin: string | null; - description: string | null; - totalVolumes: number | null; - color: string | null; - year: number | null; - rating: { - anilist: number; - mal: number; - kitsu: number; - }; - popularity: { - anilist: number; - mal: number; - kitsu: number; - }; - genres: Genres[]; - type: Type; - format: Format; - relations: Relations[]; - totalChapters: number | null; - chapters: { - latest: { - updatedAt: number; - latestChapter: number; - latestTitle: string; - }; - data: ChapterData[]; - }; - tags: string[]; - artwork: Artwork[]; - characters: Character[]; -}; - -export interface Character { - name: string; - image: string; - voiceActor: { - name: string; - image: string; - }; -} - -export type Relations = { - id: string; - type: Type; - title: { - english: string | null; - romaji: string | null; - native: string | null; - }; - format: Format; - relationType: string; -}; - -export type Artwork = { - type: "banner" | "poster" | "clear_logo" | "top_banner" | "icon" | "clear_art"; - img: string; - providerId: string; -}; diff --git a/anify-backend-recode/src/mappings/impl/anime/animepahe.ts b/anify-backend/src/mappings/impl/anime/animepahe.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/anime/animepahe.ts rename to anify-backend/src/mappings/impl/anime/animepahe.ts diff --git a/anify-backend-recode/src/mappings/impl/anime/gogoanime.ts b/anify-backend/src/mappings/impl/anime/gogoanime.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/anime/gogoanime.ts rename to anify-backend/src/mappings/impl/anime/gogoanime.ts diff --git a/anify-backend-recode/src/mappings/impl/anime/index.ts b/anify-backend/src/mappings/impl/anime/index.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/anime/index.ts rename to anify-backend/src/mappings/impl/anime/index.ts diff --git a/anify-backend-recode/src/mappings/impl/anime/nineanime.ts b/anify-backend/src/mappings/impl/anime/nineanime.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/anime/nineanime.ts rename to anify-backend/src/mappings/impl/anime/nineanime.ts diff --git a/anify-backend-recode/src/mappings/impl/anime/zoro.ts b/anify-backend/src/mappings/impl/anime/zoro.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/anime/zoro.ts rename to anify-backend/src/mappings/impl/anime/zoro.ts diff --git a/anify-backend-recode/src/mappings/impl/base/anilist.ts b/anify-backend/src/mappings/impl/base/anilist.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/base/anilist.ts rename to anify-backend/src/mappings/impl/base/anilist.ts diff --git a/anify-backend-recode/src/mappings/impl/base/index.ts b/anify-backend/src/mappings/impl/base/index.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/base/index.ts rename to anify-backend/src/mappings/impl/base/index.ts diff --git a/anify-backend-recode/src/mappings/impl/base/mangadex.ts b/anify-backend/src/mappings/impl/base/mangadex.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/base/mangadex.ts rename to anify-backend/src/mappings/impl/base/mangadex.ts diff --git a/anify-backend-recode/src/mappings/impl/information/anilist.ts b/anify-backend/src/mappings/impl/information/anilist.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/information/anilist.ts rename to anify-backend/src/mappings/impl/information/anilist.ts diff --git a/anify-backend-recode/src/mappings/impl/information/comick.ts b/anify-backend/src/mappings/impl/information/comick.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/information/comick.ts rename to anify-backend/src/mappings/impl/information/comick.ts diff --git a/anify-backend-recode/src/mappings/impl/information/index.ts b/anify-backend/src/mappings/impl/information/index.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/information/index.ts rename to anify-backend/src/mappings/impl/information/index.ts diff --git a/anify-backend-recode/src/mappings/impl/information/kitsu.ts b/anify-backend/src/mappings/impl/information/kitsu.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/information/kitsu.ts rename to anify-backend/src/mappings/impl/information/kitsu.ts diff --git a/anify-backend-recode/src/mappings/impl/information/mal.ts b/anify-backend/src/mappings/impl/information/mal.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/information/mal.ts rename to anify-backend/src/mappings/impl/information/mal.ts diff --git a/anify-backend-recode/src/mappings/impl/information/mangadex.ts b/anify-backend/src/mappings/impl/information/mangadex.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/information/mangadex.ts rename to anify-backend/src/mappings/impl/information/mangadex.ts diff --git a/anify-backend-recode/src/mappings/impl/information/tvdb.ts b/anify-backend/src/mappings/impl/information/tvdb.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/information/tvdb.ts rename to anify-backend/src/mappings/impl/information/tvdb.ts diff --git a/anify-backend-recode/src/mappings/impl/manga/comick.ts b/anify-backend/src/mappings/impl/manga/comick.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/manga/comick.ts rename to anify-backend/src/mappings/impl/manga/comick.ts diff --git a/anify-backend-recode/src/mappings/impl/manga/index.ts b/anify-backend/src/mappings/impl/manga/index.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/manga/index.ts rename to anify-backend/src/mappings/impl/manga/index.ts diff --git a/anify-backend-recode/src/mappings/impl/manga/jnovels.ts b/anify-backend/src/mappings/impl/manga/jnovels.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/manga/jnovels.ts rename to anify-backend/src/mappings/impl/manga/jnovels.ts diff --git a/anify-backend-recode/src/mappings/impl/manga/mangadex.ts b/anify-backend/src/mappings/impl/manga/mangadex.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/manga/mangadex.ts rename to anify-backend/src/mappings/impl/manga/mangadex.ts diff --git a/anify-backend-recode/src/mappings/impl/manga/mangasee.ts b/anify-backend/src/mappings/impl/manga/mangasee.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/manga/mangasee.ts rename to anify-backend/src/mappings/impl/manga/mangasee.ts diff --git a/anify-backend-recode/src/mappings/impl/manga/novelupdates.ts b/anify-backend/src/mappings/impl/manga/novelupdates.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/manga/novelupdates.ts rename to anify-backend/src/mappings/impl/manga/novelupdates.ts diff --git a/anify-backend-recode/src/mappings/impl/meta/anilist.ts b/anify-backend/src/mappings/impl/meta/anilist.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/meta/anilist.ts rename to anify-backend/src/mappings/impl/meta/anilist.ts diff --git a/anify-backend-recode/src/mappings/impl/meta/index.ts b/anify-backend/src/mappings/impl/meta/index.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/meta/index.ts rename to anify-backend/src/mappings/impl/meta/index.ts diff --git a/anify-backend-recode/src/mappings/impl/meta/kitsu.ts b/anify-backend/src/mappings/impl/meta/kitsu.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/meta/kitsu.ts rename to anify-backend/src/mappings/impl/meta/kitsu.ts diff --git a/anify-backend-recode/src/mappings/impl/meta/mal.ts b/anify-backend/src/mappings/impl/meta/mal.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/meta/mal.ts rename to anify-backend/src/mappings/impl/meta/mal.ts diff --git a/anify-backend-recode/src/mappings/impl/meta/tmdb.ts b/anify-backend/src/mappings/impl/meta/tmdb.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/meta/tmdb.ts rename to anify-backend/src/mappings/impl/meta/tmdb.ts diff --git a/anify-backend-recode/src/mappings/impl/meta/tvdb.ts b/anify-backend/src/mappings/impl/meta/tvdb.ts similarity index 100% rename from anify-backend-recode/src/mappings/impl/meta/tvdb.ts rename to anify-backend/src/mappings/impl/meta/tvdb.ts diff --git a/anify-backend-recode/src/mappings/index.ts b/anify-backend/src/mappings/index.ts similarity index 100% rename from anify-backend-recode/src/mappings/index.ts rename to anify-backend/src/mappings/index.ts diff --git a/anify-backend-recode/src/proxies/executor.ts b/anify-backend/src/proxies/executor.ts similarity index 100% rename from anify-backend-recode/src/proxies/executor.ts rename to anify-backend/src/proxies/executor.ts diff --git a/anify-backend-recode/src/proxies/impl/checkProxies.ts b/anify-backend/src/proxies/impl/checkProxies.ts similarity index 100% rename from anify-backend-recode/src/proxies/impl/checkProxies.ts rename to anify-backend/src/proxies/impl/checkProxies.ts diff --git a/anify-backend-recode/src/proxies/impl/fetchProxies.ts b/anify-backend/src/proxies/impl/fetchProxies.ts similarity index 100% rename from anify-backend-recode/src/proxies/impl/fetchProxies.ts rename to anify-backend/src/proxies/impl/fetchProxies.ts diff --git a/anify-backend-recode/src/proxies/impl/scrapeProxies.ts b/anify-backend/src/proxies/impl/scrapeProxies.ts similarity index 100% rename from anify-backend-recode/src/proxies/impl/scrapeProxies.ts rename to anify-backend/src/proxies/impl/scrapeProxies.ts diff --git a/anify-backend-recode/src/proxies/index.ts b/anify-backend/src/proxies/index.ts similarity index 100% rename from anify-backend-recode/src/proxies/index.ts rename to anify-backend/src/proxies/index.ts diff --git a/anify-backend/src/scripts/buildDb.ts b/anify-backend/src/scripts/buildDb.ts deleted file mode 100644 index 7066532..0000000 --- a/anify-backend/src/scripts/buildDb.ts +++ /dev/null @@ -1,22 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import colors from "colors"; -import { execSync } from "child_process"; -import Database from "../database"; - -const scripts = ["npm run db:generate && npm run db:push && npm run db:validate"]; - -for (const script of scripts) { - try { - console.log(`Executing script: ${script}`); - execSync(script, { stdio: "inherit" }); - } catch (error) { - console.error(colors.red(`Error executing script: ${script}`)); - console.error(error); - } -} - -Database.initializeDatabase().then(() => { - console.log(colors.green("Initialized database!")); -}); diff --git a/anify-backend/src/scripts/checkEnv.ts b/anify-backend/src/scripts/checkEnv.ts deleted file mode 100644 index 7dd2142..0000000 --- a/anify-backend/src/scripts/checkEnv.ts +++ /dev/null @@ -1,31 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import colors from "colors"; -import { env } from "../env"; -const recommendedVariables = ["REDIS_URL", "REDIS_CACHE_TIME", "CENSYS_ID", "CENSYS_SECRET"]; - -let databaseType: "postgres" | null = "postgres"; - -if (env.DATABASE_TYPE) { - databaseType = env.DATABASE_TYPE === "postgres" ? "postgres" : null; - if (!databaseType) { - console.log(colors.yellow("WARNING: Invalid database type provided. Please check .env.example.")); - databaseType = "postgres"; - } -} - -if (databaseType === "postgres") { - const requiredVariables = ["DATABASE_URL"]; - for (const variable of requiredVariables) { - if (!env[variable as keyof typeof env]) { - throw new Error(colors.red(`Missing environment variable ${variable}`)); - } - } -} - -for (const variable of recommendedVariables) { - if (!env[variable as keyof typeof env]) { - console.log(colors.yellow(`WARNING: Enviornment variable ${variable} not found.`)); - } -} diff --git a/anify-backend/src/scripts/checkProxies.ts b/anify-backend/src/scripts/checkProxies.ts deleted file mode 100644 index 2d7ab8f..0000000 --- a/anify-backend/src/scripts/checkProxies.ts +++ /dev/null @@ -1,6 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import { checkCorsProxies } from "../helper/proxies"; - -checkCorsProxies().then(console.log); diff --git a/anify-backend/src/scripts/clear.ts b/anify-backend/src/scripts/clear.ts deleted file mode 100644 index e3816f1..0000000 --- a/anify-backend/src/scripts/clear.ts +++ /dev/null @@ -1,17 +0,0 @@ -import colors from "colors"; -import Database from "../database"; - -/** - * Clears the database - * @returns {Promise} - */ -export const clearDatabase = async (): Promise => { - const data = await Database.clear(); - - console.log(colors.red("Deleted") + colors.blue(` ${data.anime} `) + colors.red("anime")); - console.log(colors.red("Deleted") + colors.blue(` ${data.manga} `) + colors.red("manga")); - console.log(colors.red("Deleted") + colors.blue(` ${data.skipTimes} `) + colors.red("skip times")); - console.log(colors.red("Deleted") + colors.blue(` ${data.apiKeys} `) + colors.red("api keys")); -}; - -clearDatabase().then(() => process.exit(0)); diff --git a/anify-backend/src/scripts/createKey.ts b/anify-backend/src/scripts/createKey.ts deleted file mode 100644 index bd7a524..0000000 --- a/anify-backend/src/scripts/createKey.ts +++ /dev/null @@ -1,9 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import { createKey } from "../keys"; - -createKey().then((data) => { - console.log(data); - process.exit(0); -}); diff --git a/anify-backend/src/scripts/export.ts b/anify-backend/src/scripts/export.ts deleted file mode 100644 index e45c724..0000000 --- a/anify-backend/src/scripts/export.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { existsSync, promises as fs } from "fs"; -import colors from "colors"; -import Database from "../database"; -import { Type } from "../mapping"; - -const BATCH_SIZE = 100; // Specify the desired batch size - -export const exportDatabase = async () => { - if (existsSync("database.json")) { - console.log(colors.yellow("Warning: database.json already exists, overwriting...")); - } - - console.log(colors.blue("Exporting database...")); - - try { - const anime = await Database.fetchAll(Type.ANIME); - const manga = await Database.fetchAll(Type.MANGA); - const skipTimes = await Database.fetchAllSkipTimes(); - const keys = await Database.fetchAllAPIKeys(); - - const data = { - anime, - manga, - skipTimes, - keys, - }; - - // Write in batches - console.log(colors.blue("Writing database to file...")); - await fs.writeFile(`database.json`, "", "utf8"); - await writeDataInBatches(data, BATCH_SIZE); - - console.log(colors.green(`Database exported successfully! Exported ${anime?.length} anime, ${manga?.length} manga, ${skipTimes?.length} skip times, and ${keys?.length} API keys.`)); - } catch (error) { - console.error(colors.red("Error exporting database:"), error); - } -}; - -const writeDataInBatches = async (data: any, batchSize: number) => { - /* - const keys = Object.keys(data); - - for (const key of keys) { - const dataArray = data[key]; - const numBatches = Math.ceil(dataArray.length / batchSize); - - console.log(colors.green(`Writing ${key} to file...`)); - - for (let i = 0; i < numBatches; i++) { - const startIndex = i * batchSize; - const endIndex = Math.min((i + 1) * batchSize, dataArray.length); - const batchData = dataArray.slice(startIndex, endIndex); - - console.log(colors.green(`Writing ${key} batch ${i + 1} of ${numBatches}...`)); - - await fs.appendFile(`database.json`, JSON.stringify({ [key]: batchData }), "utf8"); - - console.log(colors.green(`Wrote ${key} batch ${i + 1} of ${numBatches}!`)); - } - } - */ - await fs.writeFile(`database.json`, JSON.stringify(data)); -}; - -exportDatabase().then(() => process.exit(0)); diff --git a/anify-backend/src/scripts/flushSafe.ts b/anify-backend/src/scripts/flushSafe.ts deleted file mode 100644 index 987c740..0000000 --- a/anify-backend/src/scripts/flushSafe.ts +++ /dev/null @@ -1,6 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import { flushSafely } from "../keys"; - -flushSafely().then(process.exit(0)); diff --git a/anify-backend/src/scripts/import.ts b/anify-backend/src/scripts/import.ts deleted file mode 100644 index 346adbf..0000000 --- a/anify-backend/src/scripts/import.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { existsSync, promises as fs } from "fs"; -import colors from "colors"; -import Database from "../database"; -import { Anime, Manga, Type } from "../mapping"; - -/** - * Imports the database from a JSON file. - * @returns {Promise} - */ -export const importDatabase = async (): Promise => { - if (!existsSync("database.json")) { - console.error(colors.red("Error importing database: database.json does not exist")); - throw new Error("Database import failed"); - } - - console.log(colors.blue("Importing database...")); - - let createdAnime = 0; - let updatedAnime = 0; - let createdManga = 0; - let updatedManga = 0; - - try { - const data = JSON.parse(await fs.readFile("database.json", "utf8")); - - let { anime, manga, skipTimes, keys } = data; - - if (!anime) anime = []; - if (!manga) manga = []; - if (!skipTimes) skipTimes = []; - if (!keys) keys = []; - - for (let i = 0; i < anime.length; i++) { - const possible = await Database.info(anime[i].id); - if (possible) { - const media: Anime = anime[i]; - - let update = false; - for (const mapping of media.mappings) { - const curMapping = possible.mappings.find((m) => m.providerId === mapping.providerId); - if (!curMapping || curMapping.id != mapping.id || curMapping.similarity != mapping.similarity) { - update = true; - break; - } - } - - if (!update) { - if (media.bannerImage != possible.bannerImage || media.coverImage != possible.coverImage) update = true; - } - - if (update) { - await Database.update(possible.id, possible.type, media); - console.log(colors.green("Updated anime entry for ") + colors.blue(anime[i].title.english ?? anime[i].title.romaji ?? anime[i].title.native) + colors.green(".")); - - updatedAnime++; - continue; - } else { - continue; - } - } - - await Database.createEntry(anime[i]); - console.log(colors.green("Created anime entry for ") + colors.blue(anime[i].title.english ?? anime[i].title.romaji ?? anime[i].title.native) + colors.green(".")); - createdAnime++; - } - - for (let i = 0; i < manga.length; i++) { - const possible = await Database.info(manga[i].id); - if (possible) { - const media: Manga = manga[i]; - - let update = false; - for (const mapping of media.mappings) { - const curMapping = possible.mappings.find((m) => m.providerId === mapping.providerId); - if (!curMapping || curMapping.id != mapping.id || curMapping.similarity != mapping.similarity) { - update = true; - break; - } - } - - if (!update) { - if (media.bannerImage != possible.bannerImage || media.coverImage != possible.coverImage) update = true; - } - - if (update) { - await Database.update(possible.id, possible.type, media); - console.log(colors.green("Updated manga entry for ") + colors.blue(manga[i].title.english ?? manga[i].title.romaji ?? manga[i].title.native) + colors.green(".")); - - updatedManga++; - continue; - } else { - continue; - } - } - - await Database.createEntry(manga[i]); - console.log(colors.green("Created manga entry for ") + colors.blue(manga[i].title.english ?? manga[i].title.romaji ?? manga[i].title.native) + colors.green(".")); - - createdManga++; - } - - for (const skipTime of skipTimes) { - await Database.updateSkipTimes(skipTime.id, skipTime.episodes); - console.log(colors.green("Created skip time ") + colors.blue(JSON.stringify(skipTime.id)) + colors.green(".")); - } - - for (const key of keys) { - await Database.insertAPIKey(key); - console.log(colors.green("Created API key ") + colors.blue(key.key) + colors.green(".")); - } - - console.log(colors.green(`Imported ${createdAnime} anime entries, ${updatedAnime} updated.`)); - console.log(colors.green(`Imported ${createdManga} manga entries, ${updatedManga} updated.`)); - return; - } catch (error) { - console.error(colors.red(`Error importing database: ${error}`)); - throw new Error("Database import failed"); - } -}; - -importDatabase().then(() => process.exit(0)); diff --git a/anify-backend/src/scripts/scrapeProxies.ts b/anify-backend/src/scripts/scrapeProxies.ts deleted file mode 100644 index 6934260..0000000 --- a/anify-backend/src/scripts/scrapeProxies.ts +++ /dev/null @@ -1,6 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import { scrapeCorsProxies } from "../helper/proxies"; - -scrapeCorsProxies().then(console.log); diff --git a/anify-backend-recode/src/server/impl/chapters.ts b/anify-backend/src/server/impl/chapters.ts similarity index 100% rename from anify-backend-recode/src/server/impl/chapters.ts rename to anify-backend/src/server/impl/chapters.ts diff --git a/anify-backend-recode/src/server/impl/episodeCovers.ts b/anify-backend/src/server/impl/episodeCovers.ts similarity index 100% rename from anify-backend-recode/src/server/impl/episodeCovers.ts rename to anify-backend/src/server/impl/episodeCovers.ts diff --git a/anify-backend-recode/src/server/impl/episodes.ts b/anify-backend/src/server/impl/episodes.ts similarity index 100% rename from anify-backend-recode/src/server/impl/episodes.ts rename to anify-backend/src/server/impl/episodes.ts diff --git a/anify-backend-recode/src/server/impl/info.ts b/anify-backend/src/server/impl/info.ts similarity index 100% rename from anify-backend-recode/src/server/impl/info.ts rename to anify-backend/src/server/impl/info.ts diff --git a/anify-backend-recode/src/server/impl/pages.ts b/anify-backend/src/server/impl/pages.ts similarity index 100% rename from anify-backend-recode/src/server/impl/pages.ts rename to anify-backend/src/server/impl/pages.ts diff --git a/anify-backend-recode/src/server/impl/recent.ts b/anify-backend/src/server/impl/recent.ts similarity index 100% rename from anify-backend-recode/src/server/impl/recent.ts rename to anify-backend/src/server/impl/recent.ts diff --git a/anify-backend-recode/src/server/impl/relations.ts b/anify-backend/src/server/impl/relations.ts similarity index 100% rename from anify-backend-recode/src/server/impl/relations.ts rename to anify-backend/src/server/impl/relations.ts diff --git a/anify-backend-recode/src/server/impl/search.ts b/anify-backend/src/server/impl/search.ts similarity index 100% rename from anify-backend-recode/src/server/impl/search.ts rename to anify-backend/src/server/impl/search.ts diff --git a/anify-backend-recode/src/server/impl/searchAdvanced.ts b/anify-backend/src/server/impl/searchAdvanced.ts similarity index 100% rename from anify-backend-recode/src/server/impl/searchAdvanced.ts rename to anify-backend/src/server/impl/searchAdvanced.ts diff --git a/anify-backend-recode/src/server/impl/seasonal.ts b/anify-backend/src/server/impl/seasonal.ts similarity index 100% rename from anify-backend-recode/src/server/impl/seasonal.ts rename to anify-backend/src/server/impl/seasonal.ts diff --git a/anify-backend-recode/src/server/impl/sources.ts b/anify-backend/src/server/impl/sources.ts similarity index 100% rename from anify-backend-recode/src/server/impl/sources.ts rename to anify-backend/src/server/impl/sources.ts diff --git a/anify-backend-recode/src/server/impl/stats.ts b/anify-backend/src/server/impl/stats.ts similarity index 100% rename from anify-backend-recode/src/server/impl/stats.ts rename to anify-backend/src/server/impl/stats.ts diff --git a/anify-backend/src/server/index.ts b/anify-backend/src/server/index.ts index 6bcab6d..c51afb0 100644 --- a/anify-backend/src/server/index.ts +++ b/anify-backend/src/server/index.ts @@ -1,2019 +1,54 @@ -import express from "express"; -import { rateLimit } from "express-rate-limit"; - -import cluster from "node:cluster"; -import os from "node:os"; - -import bodyParser from "body-parser"; -import cors from "cors"; -import cookieParser from "cookie-parser"; -import expressDomainMiddleware from "express-domain-middleware"; +import { readdirSync } from "node:fs"; +import { join } from "node:path"; import Redis from "ioredis"; -import RedisStore from "rate-limit-redis"; import colors from "colors"; -import queues from "../worker"; -import { ANIME_PROVIDERS, Anime, Format, Genres, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, Manga, Type, infoProviders } from "../mapping"; -import { fetchEpisodes } from "../content/impl/episodes"; -import { fetchChapters } from "../content/impl/chapters"; -import { fetchSources } from "../content/impl/sources"; -import { fetchPages } from "../content/impl/pages"; -import { loadSeasonal } from "../lib/season"; -import { loadSkipTimes } from "../lib/skipTimes"; -import { SubType } from "../mapping/impl/anime"; -import { loadEpisodeCovers } from "../content/impl/episodes/episodeCovers"; -import { checkAPIKey, importKeys, masterKey, updateRequests } from "../keys"; -import { fetchSchedule } from "../content/impl/schedule"; -import Database from "../database"; -import { createLoop } from "../tasks"; -import { AnimeInfo, MangaInfo } from "../mapping/impl/information"; import { env } from "../env"; -const port = env.PORT; - -const app = express(); -const numCPUs = os.cpus().length; - -const corsOptions = { - origin: "*", - methods: ["POST", "GET", "PATCH", "DELETE", "OPTIONS"], - allowedHeaders: ["Content-Type", "Authorization"], -}; - -let redis = new Redis((env.REDIS_URL as string) || "redis://localhost:6379"); - -const cacheTime = env.REDIS_CACHE_TIME; - -const whitelist = env.API_KEY_WHITELIST; - -app.use(cors(corsOptions)); -app.use(bodyParser.urlencoded({ extended: true })); -app.use(bodyParser.json()); -app.use(expressDomainMiddleware); -app.use(cookieParser()); - -app.get("/", async (request, reply) => { - return reply.json("Documentation can be viewed at https://docs.anify.tv. Join our Discord https://anify.tv/discord for more information."); -}); - -app.use(checkAPIKey); - -if (!env.REDIS_URL) { - console.log(colors.yellow("No Redis URL provided. Caching will be disabled.")); - redis = { - get: async () => null, - set: (): Promise<"OK"> => Promise.resolve("OK"), - on: () => Redis.prototype, - keys: async () => [], - connect: async () => void 0, - call: async () => void 0, - } as any; -} else { - const statsRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "stats-limiter", - }), - }); - - const genresRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 80, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "stats-limiter", - }), - }); - - const tagsRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 80, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "stats-limiter", - }), - }); - - const searchRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 25, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "search-limiter", - }), - }); - - const scheduleRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "schedule-limiter", - }), - }); - - const recentRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "reecnt-limiter", - }), - }); - - const seasonalRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 50, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "seasonal-limiter", - }), - }); - - const infoRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 75, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "info-limiter", - }), - }); - - const mediaRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 75, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "media-limiter", - }), - }); - - const relationsRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "relations-limiter", - }), - }); - - const episodesRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 40, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "episodes-limiter", - }), - }); - - const chaptersRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 40, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "chapters-limiter", - }), - }); - - const sourcesRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "sources-limiter", - }), - }); - - const pagesRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "pages-limiter", - }), - }); - - const episodeCoversRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 40, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "episode-covers-limiter", - }), - }); - - app.use("/stats", statsRateLimit); - - app.use("/genres", genresRateLimit); - - app.use("/tags", tagsRateLimit); - - app.use("/search", searchRateLimit); - app.use("/search/:type/:query", searchRateLimit); - - app.use("/search-advanced", searchRateLimit); - - app.use("/seasonal", seasonalRateLimit); - app.use("/seasonal/:type", seasonalRateLimit); - - app.use("/schedule", scheduleRateLimit); - - app.use("/recent", recentRateLimit); - - app.use("/info", infoRateLimit); - app.use("/info/:id", infoRateLimit); - - app.use("/media", mediaRateLimit); - app.use("/media/:providerId/:id", mediaRateLimit); - - app.use("/relations", relationsRateLimit); - app.use("/relations/:id", relationsRateLimit); - - app.use("/episodes", episodesRateLimit); - app.use("/episodes/:id", episodesRateLimit); - app.use("/episodes-mal", episodesRateLimit); - app.use("/episodes-mal/:id", episodesRateLimit); - - app.use("/chapters", chaptersRateLimit); - app.use("/chapters/:id", chaptersRateLimit); - app.use("/chapters-mal", chaptersRateLimit); - app.use("/chapters-mal/:id", chaptersRateLimit); - - app.use("/sources", sourcesRateLimit); - app.use("/sources-mal", sourcesRateLimit); - - app.use("/pages", pagesRateLimit); - app.use("/pages-mal", pagesRateLimit); - - app.use("/episode-covers", episodeCoversRateLimit); - app.use("/episode-covers-mal", episodeCoversRateLimit); -} - -app.get("/providers", async (request, reply) => { - reply.json({ - anime: ANIME_PROVIDERS.map((provider) => { - return { - id: provider.id, - url: provider.url, - formats: provider.formats, - subTypes: provider.subTypes, - headers: provider.headers, - }; - }), - manga: MANGA_PROVIDERS.map((provider) => { - return { - id: provider.id, - url: provider.url, - formats: provider.formats, - }; - }), - info: INFORMATION_PROVIDERS.map((provider) => { - return { - id: provider.id, - url: provider.url, - sharedArea: provider.sharedArea, - priorityArea: provider.priorityArea, - }; - }), - meta: META_PROVIDERS.map((provider) => { - return { - id: provider.id, - url: provider.url, - formats: provider.formats, - }; - }), - }); -}); - -app.get("/stats", async (request, reply) => { - const cached = await redis.get(`stats`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await Database.count(); - - await redis.set(`stats`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.post("/stats", async (request, reply) => { - const cached = await redis.get(`stats`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await Database.count(); - - await redis.set(`stats`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.get("/genres", async (request, reply) => { - const cached = await redis.get(`genres`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const animeGenres = await Database.fetchAll(Type.ANIME); - const mangaGenres = await Database.fetchAll(Type.MANGA); - - const genres = { - anime: animeGenres.map((anime) => anime.genres).flat(), - manga: mangaGenres.map((manga) => manga.genres).flat(), - }; - - // Remove duplicates - genres.anime = [...new Set(genres.anime)]; - genres.manga = [...new Set(genres.manga)]; - - // Combine genres - const genresList = [...new Set([...genres.anime, ...genres.manga])]; - - // Sort by alphabetical order - genresList.sort(); - - await redis.set(`genres`, JSON.stringify(genresList), "EX", cacheTime); - - return reply.json(genresList); -}); - -app.post("/genres", async (request, reply) => { - const cached = await redis.get(`genres`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const animeGenres = await Database.fetchAll(Type.ANIME); - const mangaGenres = await Database.fetchAll(Type.MANGA); - - const genres = { - anime: animeGenres.map((anime) => anime.genres).flat(), - manga: mangaGenres.map((manga) => manga.genres).flat(), - }; - - // Remove duplicates - genres.anime = [...new Set(genres.anime)]; - genres.manga = [...new Set(genres.manga)]; - - // Combine genres - const genresList = [...new Set([...genres.anime, ...genres.manga])]; - - // Sort by alphabetical order - genresList.sort(); - - await redis.set(`genres`, JSON.stringify(genresList), "EX", cacheTime); - - return reply.json(genresList); -}); - -app.get("/tags", async (request, reply) => { - const cached = await redis.get(`tags`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const animeTags = await Database.fetchAll(Type.ANIME); - const mangaTags = await Database.fetchAll(Type.MANGA); - - const tags = { - anime: animeTags.map((anime) => anime.tags).flat(), - manga: mangaTags.map((manga) => manga.tags).flat(), - }; - - // Remove duplicates - tags.anime = [...new Set(tags.anime)]; - tags.manga = [...new Set(tags.manga)]; - - // Combine genres - const tagsList = [...new Set([...tags.anime, ...tags.manga])]; - - // Sort by alphabetical order - tagsList.sort(); - - await redis.set(`tags`, JSON.stringify(tagsList), "EX", cacheTime); - - return reply.json(tagsList); -}); - -app.post("/tags", async (request, reply) => { - const cached = await redis.get(`tags`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const animeTags = await Database.fetchAll(Type.ANIME); - const mangaTags = await Database.fetchAll(Type.MANGA); - - const tags = { - anime: animeTags.map((anime) => anime.tags).flat(), - manga: mangaTags.map((manga) => manga.tags).flat(), - }; - - // Remove duplicates - tags.anime = [...new Set(tags.anime)]; - tags.manga = [...new Set(tags.manga)]; - - // Combine genres - const tagsList = [...new Set([...tags.anime, ...tags.manga])]; - - // Sort by alphabetical order - tagsList.sort(); - - await redis.set(`tags`, JSON.stringify(tagsList), "EX", cacheTime); - - return reply.json(tagsList); -}); - -/** - * Searches for items of the given type based on the provided query. - * - * @param {String} type - The type of items to search for (anime, manga, novel). - * @param {String} query - The search query. - * - * @throws {400} Invalid type - If the provided type is not valid. - * @throws {400} Invalid query - If the provided query is invalid. - */ -app.get("/search/:type/:query", async (request, reply) => { - const { query } = request.params as { query: string }; - let { type } = request.params as { type: string }; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query || query.length === 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search:${originalType}:${query}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.search(query, type.toUpperCase() as Type, formats, 0, 20); - if (existing.length === 0) { - queues.searchQueue.add({ type: type.toUpperCase() as Type, query: query, formats: formats }); - - await redis.set(`search:${originalType}:${query}`, JSON.stringify([]), "EX", cacheTime); - - return reply.json([]); - } else { - await redis.set(`search:${originalType}:${query}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } -}); - -/** - * Searches for items of the given type based on the provided query. - * - * @param {String} type - The type of items to search for (anime, manga, novel). - * @param {String} query - The search query. - * - * @throws {400} Invalid type - If the provided type is not valid. - * @throws {400} Invalid query - If the provided query is invalid. - */ -app.get("/search", async (request, reply) => { - const { query } = request.query as { query: string }; - let { type } = request.query as { type: string }; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query || query.length === 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; +export const redis: Redis = env.REDIS_URL + ? new Redis((env.REDIS_URL as string) || "redis://localhost:6379") + : ({ + get: async () => null, + set: (): Promise<"OK"> => Promise.resolve("OK"), + on: () => Redis.prototype, + keys: async () => [], + connect: async () => void 0, + call: async () => void 0, + } as any); - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search:${originalType}:${query}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.search(query, type.toUpperCase() as Type, formats, 0, 20); - if (existing.length === 0) { - queues.searchQueue.add({ type: type.toUpperCase() as Type, query: query, formats: formats }); - - await redis.set(`search:${originalType}:${query}`, JSON.stringify([]), "EX", cacheTime); - - return reply.json([]); - } else { - await redis.set(`search:${originalType}:${query}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } -}); - -/** - * Searches for items of the given type based on the provided query. - * - * @param {String} type - The type of items to search for (anime, manga, novel). - * @param {String} query - The search query. - * - * @throws {400} Invalid type - If the provided type is not valid. - * @throws {400} Invalid query - If the provided query is invalid. - */ -app.post("/search", async (request, reply) => { - const { query } = request.body as any; - let { type } = request.body as any; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query || query.length === 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search:${originalType}:${query}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.search(query, type.toUpperCase(), formats, 0, 20); - if (existing.length === 0) { - queues.searchQueue.add({ type: type.toUpperCase(), query: query, formats: formats }); - - await redis.set(`search:${originalType}:${query}`, JSON.stringify([]), "EX", cacheTime); - - return reply.json([]); - } else { - await redis.set(`search:${originalType}:${query}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } -}); - -app.get("/search-advanced", async (request, reply) => { - const { query } = request.query as { query: string }; - let { type, page, genres, genresExcluded, tags, tagsExcluded, year } = request.query as { type: string; page: string; genres: string[]; genresExcluded: string[]; tags: string[]; tagsExcluded: string[]; year: string }; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query && String(query).length != 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - if (!genres) genres = []; - if (!genresExcluded) genresExcluded = []; - if (!tags) tags = []; - if (!tagsExcluded) tagsExcluded = []; - if (!year || isNaN(Number(year))) year = "0"; - - if (!page || isNaN(Number(page))) page = "1"; - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; +export const cacheTime = env.REDIS_CACHE_TIME || 60 * 60 * 24 * 7 * 2; - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search-genres:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.searchAdvanced(query, type.toUpperCase() as Type, formats, Number(page), 40, genres as Genres[], genresExcluded as Genres[], Number(year), tags, tagsExcluded); - if (existing.length === 0) { - const newData: Anime[] | Manga[] = []; - - const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).searchAdvanced(query, type.toUpperCase() as Type, formats, Number(page), 2, genres as Genres[], genresExcluded as Genres[], Number(year), tags, tagsExcluded); - for (let i = 0; i < (data ?? []).length; i++) { - const item = data![i]; - const possible = await Database.info((item as any).aniListId); - if (possible) { - let canPush = true; - - for (const genre of genres) { - if (!possible.genres.includes(genre as Genres)) { - canPush = false; - break; - } - } - for (const tag of tags) { - if (!possible.tags.includes(tag)) { - canPush = false; - break; - } - } - for (const genre of genresExcluded) { - if (possible.genres.includes(genre as Genres)) { - canPush = false; - break; - } - } - for (const tag of tagsExcluded) { - if (possible.tags.includes(tag)) { - canPush = false; - break; - } - } - - if (canPush) newData.push(possible as any); - } else { - queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); - } - } - - if (newData.length === 0) { - if (genres.length === 0 && genresExcluded.length === 0 && tags.length === 0 && Number(year) === 0 && tagsExcluded.length === 0) { - const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).search(query, type.toUpperCase() as Type, formats, page, 2); - for (let i = 0; i < (data ?? []).length; i++) { - const item = data![i]; - const possible = await Database.info((item as any).aniListId); - if (possible) newData.push(possible as any); - else queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); - } - - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); - return reply.json(newData); - } +export const start = async () => { + const routes: { [key: string]: { path: string; handler: (req: Request) => Promise } } = {}; + const routeFiles = readdirSync(join(import.meta.dir, "./impl")); + for (const file of routeFiles) { + const routeModule = await import(join(import.meta.dir, "./impl", file)); + const route = routeModule.default; + + if (route) { + const { path, handler } = route; + routes[path] = { path, handler }; } - - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); - return reply.json(newData); - } else { - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); } -}); - -app.post("/search-advanced", async (request, reply) => { - const { query } = request.body as { query: string }; - let { type, page, genres, genresExcluded, tags, tagsExcluded, year } = request.body as { type: string; page: number; genres: string[]; genresExcluded: string[]; tags: string[]; tagsExcluded: string[]; year: number }; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query && String(query).length != 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - if (!genres) genres = []; - if (!genresExcluded) genresExcluded = []; - if (!tags) tags = []; - if (!tagsExcluded) tagsExcluded = []; - if (!year) year = 0; - - if (!page) page = 1; - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.searchAdvanced(query, type.toUpperCase() as Type, formats, page, 40, genres as Genres[], genresExcluded as Genres[], year, tags, tagsExcluded); - if (existing.length === 0) { - const newData: Anime[] | Manga[] = []; - - const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).searchAdvanced(query, type.toUpperCase() as Type, formats, Number(page), 2, genres as Genres[], genresExcluded as Genres[], Number(year), tags, tagsExcluded); - for (let i = 0; i < (data ?? []).length; i++) { - const item = data![i]; - const possible = await Database.info((item as any).aniListId); - if (possible) { - let canPush = true; - - for (const genre of genres) { - if (!possible.genres.includes(genre as Genres)) { - canPush = false; - break; - } - } - for (const tag of tags) { - if (!possible.tags.includes(tag)) { - canPush = false; - break; - } - } - for (const genre of genresExcluded) { - if (possible.genres.includes(genre as Genres)) { - canPush = false; - break; - } - } - for (const tag of tagsExcluded) { - if (possible.tags.includes(tag)) { - canPush = false; - break; - } - } - if (canPush) newData.push(possible as any); - } else { - queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); - } - } + Bun.serve({ + port: env.PORT, + async fetch(req: Request) { + const url = new URL(req.url); + if (url.pathname === "/") return new Response("Welcome to Anify API! 🎉 Documentation can be viewed at https://docs.anify.tv. Join our Discord https://anify.tv/discord for more information.", { headers: { "Content-Type": "application/json" } }); - if (newData.length === 0) { - if (genres.length === 0 && genresExcluded.length === 0 && tags.length === 0 && Number(year) === 0 && tagsExcluded.length === 0) { - const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).search(query, type.toUpperCase() as Type, formats, page, 2); - for (let i = 0; i < (data ?? []).length; i++) { - const item = data![i]; - const possible = await Database.info((item as any).aniListId); - if (possible) newData.push(possible as any); - else queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); - } + const pathName = `/${url.pathname.split("/").slice(1)[0]}`; - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); - return reply.json(newData); + if (routes[pathName]) { + const { path, handler } = routes[pathName]; + return handler(req); } - } - - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); - return reply.json(newData); - } else { - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } -}); - -/** - * Retrieves seasonal items of the given type. - * - * @param {String} type - The type of items to retrieve (anime, manga, novel). - * - * @throws {400} Invalid type - If the provided type is not valid. - */ -app.get("/seasonal/:type", async (request, reply) => { - let { type } = request.params as { type: string }; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`seasonal:${originalType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const aniListData = await loadSeasonal({ type: type.toUpperCase() as Type, formats: formats }); - const data = await Database.seasonal(aniListData?.trending, aniListData?.popular, aniListData?.top, aniListData?.seasonal); - - await redis.set(`seasonal:${originalType}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -/** - * Retrieves seasonal items of the given type. - * - * @param {String} type - The type of items to retrieve (anime, manga, novel). - * - * @throws {400} Invalid type - If the provided type is not valid. - */ -app.get("/seasonal", async (request, reply) => { - let { type } = request.query as { type: string }; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`seasonal:${originalType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const aniListData = await loadSeasonal({ type: type.toUpperCase() as Type, formats: formats }); - const data = await Database.seasonal(aniListData?.trending, aniListData?.popular, aniListData?.top, aniListData?.seasonal); - - await redis.set(`seasonal:${originalType}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -/** - * Retrieves seasonal items of the given type. - * - * @param {String} type - The type of items to retrieve (anime, manga, novel). - * - * @throws {400} Invalid type - If the provided type is not valid. - */ -app.post("/seasonal", async (request, reply) => { - let { type } = request.body as { type: string }; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`seasonal:${originalType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const aniListData = await loadSeasonal({ type: type.toUpperCase() as Type, formats: formats }); - const data = await Database.seasonal(aniListData?.trending, aniListData?.popular, aniListData?.top, aniListData?.seasonal); - - await redis.set(`seasonal:${originalType}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.get("/schedule", async (request, reply) => { - const cached = await redis.get(`schedule`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await fetchSchedule(); - - await redis.set(`schedule`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.post("/schedule", async (request, reply) => { - const cached = await redis.get(`schedule`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await fetchSchedule(); - - await redis.set(`schedule`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.get("/recent", async (request, reply) => { - let { type, page } = request.query as { type: string; page: string }; - if (!page || isNaN(Number(page))) page = "1"; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`recent:${originalType}:${page}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await Database.recent(type.toUpperCase() as Type, formats, Number(page)); - - await redis.set(`recent:${originalType}:${page}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); + return new Response(JSON.stringify({ error: "Route not found" }), { status: 404, headers: { "Content-Type": "application/json" } }); + }, + }); -app.post("/recent", async (request, reply) => { - let { type, page } = request.body as { type: string; page: number }; - if (!page) page = 1; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`recent:${originalType}:${page}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await Database.recent(type.toUpperCase() as Type, formats, page); - - await redis.set(`recent:${originalType}:${page}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/info/:id", async (request, reply) => { - const { id } = request.params as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`info:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.info(id); - if (existing) { - await redis.set(`info:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/info", async (request, reply) => { - const { id } = request.query as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`info:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.info(id); - if (existing) { - await redis.set(`info:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.post("/info", async (request, reply) => { - const { id } = request.body as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`info:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.info(id); - if (existing) { - await redis.set(`info:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid provider ID - If there is no provided provider ID. - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/media/:providerId/:id", async (request, reply) => { - const { providerId, id } = request.params as { providerId: string; id: string }; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID" }); - } - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`media:${providerId}:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.media(providerId, id); - if (existing) { - await redis.set(`media:${providerId}:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid provider ID - If there is no provided provider ID. - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/media", async (request, reply) => { - const { providerId, id } = request.query as { providerId: string; id: string }; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID" }); - } - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`media:${providerId}:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.media(providerId, id); - if (existing) { - await redis.set(`media:${providerId}:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid provider ID - If there is no provided provider ID. - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.post("/media", async (request, reply) => { - const { providerId, id } = request.body as { providerId: string; id: string }; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID" }); - } - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`media:${providerId}:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.media(providerId, id); - if (existing) { - await redis.set(`media:${providerId}:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves relations for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/relations/:id", async (request, reply) => { - const { id } = request.params as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`relations:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.relations(id); - if (existing) { - await redis.set(`relations:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves relations for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/relations", async (request, reply) => { - const { id } = request.query as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`relations:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.relations(id); - if (existing) { - await redis.set(`relations:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves relations for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.post("/relations", async (request, reply) => { - const { id } = request.body as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`relations:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.relations(id); - if (existing) { - await redis.set(`relations:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves episodes for a media. - * - * @param {String} id - The ID to get episodes from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no episodes. - */ -app.get("/episodes/:id", async (request, reply) => { - const { id } = request.params as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`episodes:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchEpisodes(id); - if (existing) { - await redis.set(`episodes:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves episodes for a media. - * - * @param {String} id - The ID to get episodes from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no episodes. - */ -app.get("/episodes", async (request, reply) => { - const { id } = request.query as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`episodes:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchEpisodes(id); - if (existing) { - await redis.set(`episodes:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves episodes for a media. - * - * @param {String} id - The ID to get episodes from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no episodes. - */ -app.post("/episodes", async (request, reply) => { - const { id } = request.body as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`episodes:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchEpisodes(id); - if (existing) { - await redis.set(`episodes:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves chapters for a media. - * - * @param {String} id - The ID to get chapters from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no chapters. - */ -app.get("/chapters/:id", async (request, reply) => { - const { id } = request.params as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`chapters:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchChapters(id); - if (existing) { - await redis.set(`chapters:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves chapters for a media. - * - * @param {String} id - The ID to get chapters from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no chapters. - */ -app.get("/chapters", async (request, reply) => { - const { id } = request.query as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`chapters:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchChapters(id); - if (existing) { - await redis.set(`chapters:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves chapters for a media. - * - * @param {String} id - The ID to get chapters from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no chapters. - */ -app.post("/chapters", async (request, reply) => { - const { id } = request.body as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`chapters:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchChapters(id); - if (existing) { - await redis.set(`chapters:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -app.get("/sources", async (request, reply) => { - const { providerId, watchId, episode, id, server } = request.query as any; - let { subType } = request.query as any; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!watchId || watchId.length === 0) { - return reply.status(400).send({ error: "Invalid watch ID." }); - } - - if (!episode) { - return reply.status(400).send({ error: "Invalid episode." }); - } - - if (subType && subType.toLowerCase() != SubType.DUB && subType.toLowerCase() != SubType.SUB) { - return reply.status(400).send({ error: "Invalid subtype given." }); - } - - if (!subType) subType = SubType.SUB; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`sources:${providerId}:${watchId}:${server}:${subType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchSources(providerId, watchId, subType, server); - if (existing) { - const skipTimes = await loadSkipTimes({ toInsert: existing, id: id, episode: episode }).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - existing.intro = skipTimes?.intro ?? { - start: 0, - end: 0, - }; - existing.outro = skipTimes?.outro ?? { - start: 0, - end: 0, - }; - - await redis.set(`sources:${providerId}:${watchId}:${server}:${subType}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - - return reply.status(404).send({ error: "Not found", sources: existing }); -}); - -app.post("/sources", async (request, reply) => { - const { providerId, watchId, server, episode, id } = request.body as any; - let { subType } = request.body as any; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!watchId || watchId.length === 0) { - return reply.status(400).send({ error: "Invalid watch ID." }); - } - - if (!episode) { - return reply.status(400).send({ error: "Invalid episode." }); - } - - if (subType && subType.toLowerCase() != SubType.DUB && subType.toLowerCase() != SubType.SUB) { - return reply.status(400).send({ error: "Invalid subtype given." }); - } - if (!subType) subType = SubType.SUB; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`sources:${providerId}:${watchId}:${server}:${subType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchSources(providerId, watchId, subType, server); - if (existing) { - const skipTimes = await loadSkipTimes({ toInsert: existing, id: id, episode: episode }).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - existing.intro = skipTimes?.intro ?? { - start: 0, - end: 0, - }; - existing.outro = skipTimes?.outro ?? { - start: 0, - end: 0, - }; - - await redis.set(`sources:${providerId}:${watchId}:${server}:${subType}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - - return reply.status(404).send({ error: "Not found", sources: existing }); -}); - -app.get("/skip-times/:id", async (request, reply) => { - const { id } = request.params as any; - - if (!id) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`skip-times:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const skipTimes = await Database.findSkipTimes(id).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - if (!skipTimes) { - return reply.status(404).send({ error: "Not found." }); - } - - await redis.set(`skip-times:${id}`, JSON.stringify(skipTimes), "EX", cacheTime); - - return reply.json(skipTimes); -}); - -app.get("/skip-times", async (request, reply) => { - const { id } = request.query as any; - - if (!id) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`skip-times:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const skipTimes = await Database.findSkipTimes(id).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - if (!skipTimes) { - return reply.status(404).send({ error: "Not found." }); - } - - await redis.set(`skip-times:${id}`, JSON.stringify(skipTimes), "EX", cacheTime); - - return reply.json(skipTimes); -}); - -app.post("/skip-times", async (request, reply) => { - const { id } = request.body as any; - - if (!id) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`skip-times:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const skipTimes = await Database.findSkipTimes(id).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - if (!skipTimes) { - return reply.status(404).send({ error: "Not found." }); - } - - await redis.set(`skip-times:${id}`, JSON.stringify(skipTimes), "EX", cacheTime); - - return reply.json(skipTimes); -}); - -app.get("/pages/:id/:providerId/:readId", async (request, reply) => { - const { id, providerId, readId } = request.params as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!readId || readId.length === 0) { - return reply.status(400).send({ error: "Invalid read ID." }); - } - - const cached = await redis.get(`pages:${id}:${providerId}:${readId}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchPages(id, providerId, readId); - if (existing) { - await redis.set(`pages:${id}:${providerId}:${readId}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -app.get("/pages", async (request, reply) => { - const { id, providerId, readId } = request.query as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!readId || readId.length === 0) { - return reply.status(400).send({ error: "Invalid read ID." }); - } - - const cached = await redis.get(`pages:${id}:${providerId}:${readId}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchPages(id, providerId, readId); - if (existing) { - await redis.set(`pages:${id}:${providerId}:${readId}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -app.post("/pages", async (request, reply) => { - const { id, providerId, readId } = request.body as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!readId || readId.length === 0) { - return reply.status(400).send({ error: "Invalid read ID." }); - } - - const cached = await redis.get(`pages:${id}:${providerId}:${readId}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchPages(id, providerId, readId); - if (existing) { - await redis.set(`pages:${id}:${providerId}:${readId}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -app.get("/pages-download", async (request, reply) => { - const { id } = request.query as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid MixDrop ID." }); - } - - const cached = await redis.get(`pages-download:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await (await fetch(`https://api.mixdrop.co/fileinfo2?email=${env.MIXDROP_EMAIL}&key=${env.MIXDROP_KEY}&ref[]=${id}`)).json(); - - await redis.set(`pages-download:${id}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.post("/pages-download", async (request, reply) => { - const { id } = request.body as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid MixDrop ID." }); - } - - const cached = await redis.get(`pages-download:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await (await fetch(`https://api.mixdrop.co/fileinfo2?email=${env.MIXDROP_EMAIL}&key=${env.MIXDROP_KEY}&ref[]=${id}`)).json(); - - await redis.set(`pages-download:${id}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.get("/episode-covers/:id", async (request, reply) => { - const { id } = request.params as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - const cached = await redis.get(`episode-covers:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const anime = await Database.info(id); - if (!anime) { - return reply.status(404).send({ error: "Not found" }); - } - - if (anime.type === Type.ANIME) { - let covers = await loadEpisodeCovers(anime as Anime); - - if (!covers) covers = []; - - await redis.set(`episode-covers:${id}`, JSON.stringify(covers), "EX", cacheTime); - return reply.json(covers); - } else { - return reply.status(400).send({ error: "Type is not anime." }); - } -}); - -app.get("/episode-covers", async (request, reply) => { - const { id } = request.query as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - const cached = await redis.get(`episode-covers:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const anime = await Database.info(id); - if (!anime) { - return reply.status(404).send({ error: "Not found" }); - } - - if (anime.type === Type.ANIME) { - let covers = await loadEpisodeCovers(anime as Anime); - - if (!covers) covers = []; - - await redis.set(`episode-covers:${id}`, JSON.stringify(covers), "EX", cacheTime); - return reply.json(covers); - } else { - return reply.status(400).send({ error: "Type is not anime." }); - } -}); - -app.post("/episode-covers", async (request, reply) => { - const { id } = request.body as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - const cached = await redis.get(`episode-covers:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const anime = await Database.info(id); - if (!anime) { - return reply.status(404).send({ error: "Not found" }); - } - - if (anime.type === Type.ANIME) { - let covers = await loadEpisodeCovers(anime as Anime); - - if (!covers) covers = []; - - await redis.set(`episode-covers:${id}`, JSON.stringify(covers), "EX", cacheTime); - return reply.json(covers); - } else { - return reply.status(400).send({ error: "Type is not anime." }); - } -}); - -// Admin routes -app.get("/update-keys", async (request, reply) => { - if (masterKey === request.query.apikey) { - await updateRequests(); - - return reply.json({ success: "true" }); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -app.get("/key", async (request, reply) => { - const id = request.query.id as string; - - if (!id) return reply.status(400).json({ error: "No ID provided" }); - - const data = await Database.getKeyById(id); - if (!data) return reply.status(404).json({ error: "Key not found" }); - - return reply.json(data); -}); - -app.get("/keys", async (request, reply) => { - if (masterKey === request.query.apikey) { - const data = await Database.fetchAllAPIKeys(); - - return reply.json(data); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -app.get("/assign", async (request, reply) => { - if (masterKey === request.query.apikey) { - const id = request.query.id as string; - const key = request.query.key as string; - - if (!id) return reply.status(400).json({ error: "No ID provided" }); - if (!key) return reply.status(400).json({ error: "No key provided" }); - - const exists = await Database.fetchAPIKey(key); - if (!exists) return reply.status(404).json({ error: "Key not found" }); - - const data = await Database.assignKey(key, id); - if (!data) return reply.status(401).json({ error: "Key already assigned. Please unassign the key first." }); - - return reply.json(data); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -app.get("/unassign", async (request, reply) => { - if (masterKey === request.query.apikey) { - const key = request.query.key as string; - - if (!key) return reply.status(400).json({ error: "No key provided" }); - - const exists = await Database.fetchAPIKey(key); - if (!exists) return reply.status(404).json({ error: "Key not found" }); - - const data = await Database.unassignKey(key); - - return reply.json(data); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -app.get("/delete", async (request, reply) => { - if (masterKey === request.query.apikey) { - const key = request.query.key as string; - - if (!key) return reply.status(400).json({ error: "No key provided" }); - - const data = await Database.deleteKey(key); - - return reply.json(data); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -export const start = async () => { - const masterProcess = () => Array.from(Array(numCPUs)).map(cluster.fork); - const childProcess = () => - app.listen( - { port: port }, - void ((err, address) => { - if (err) { - process.exit(1); - } - }) - ); - - if (cluster.isPrimary) { - console.log(colors.blue(`Server is now listening on ${port}`)); - masterProcess(); - await importKeys(); - await createLoop(); - } else childProcess(); - cluster.on("exit", (worker) => cluster.fork()); -}; \ No newline at end of file + console.log(colors.blue(`Server is now listening on ${env.PORT}`)); +}; diff --git a/anify-backend/src/tasks/index.ts b/anify-backend/src/tasks/index.ts deleted file mode 100644 index 84aaa05..0000000 --- a/anify-backend/src/tasks/index.ts +++ /dev/null @@ -1,131 +0,0 @@ -import Database from "../database"; -import { wait } from "../helper"; -import { generateQueryBuilder } from "../helper/generator"; -import { checkCorsProxies, scrapeCorsProxies } from "../helper/proxies"; -import { loadMapping } from "../lib/mappings"; -import { Anime, Manga, ProviderType, Type } from "../mapping"; -import { AnimeInfo, MangaInfo } from "../mapping/impl/information"; -import AniList from "../mapping/impl/information/anilist"; -import colors from "colors"; -import { returnCreatedEntry } from "../lib/entry"; -import { flushSafely, updateRequests } from "../keys"; -import { join } from "node:path"; -import { existsSync } from "node:fs"; -import { rm } from "node:fs/promises"; - -export async function createLoop(): Promise { - setInterval(async () => { - await checkCorsProxies(); - await updateRequests(); - await flushSafely(); - }, 1000 * 60 * 60 * 12); // 12 hours - - setInterval(async () => { - await scrapeCorsProxies(); - await clearMangaFolder(); - - //await remap(Type.ANIME); - //await remap(Type.MANGA); - }, 1000 * 60 * 60 * 24 * 2); // 2 days -} - -export async function clearMangaFolder(): Promise { - const folder = join(__dirname, "../lib/manga"); - if (existsSync(folder)) { - await rm(folder, { force: true, recursive: true }); - } -} - -export async function remap(type: Type): Promise { - const data = await Database.fetchAll(type); - - const aniList = new AniList(); - const season = aniList.getCurrentSeason(); - - const toRemap: string[] = []; - - for (const media of data) { - const mappings = media.mappings.filter((item) => item.providerType === ProviderType.ANIME || item.providerType === ProviderType.MANGA); - if (mappings.length < 3) { - await Database.delete(media.id); - console.log(colors.red("Deleted ") + media.title.english ?? media.title.romaji ?? media.title.native + colors.red(".")); - toRemap.push(media.id); - } - } - - if (type === Type.ANIME) { - for (const media of data) { - if (toRemap.find((x) => x === media.id)) continue; - if ((media as Anime).season === season && (media as Anime).year === new Date(Date.now()).getFullYear()) { - await Database.delete(media.id); - console.log(colors.red("Deleted ") + media.title.english ?? media.title.romaji ?? media.title.native + colors.red(".")); - toRemap.push(media.id); - } - } - } - - console.log(colors.yellow("Remapping in 3 seconds...")); - - await wait(3000); - - const chunkSize = 10; - for (let i = 0; i < toRemap.length; i += chunkSize) { - try { - const now = Date.now(); - const chunk = toRemap.slice(i, i + chunkSize); - const queries: string[] = []; - await Promise.all(chunk.map((id) => queries.push(generateQueryBuilder(id)))); - const results = await aniList.batchRequest(queries, 5); - - if (results.length === 0) continue; - const batchResults: AnimeInfo[] | MangaInfo[] = results - .reduce((accumulator, currentObject) => { - const mediaArrays = Object.values(currentObject).map((anime: any) => anime.media); - return accumulator.concat(...mediaArrays); - }, []) - .map((x: any) => { - if (!x) return null; - x.year = x.startDate?.year ?? x.seasonYear ?? 0; - return x; - }) - .filter(Boolean); - - const map = await Promise.all(batchResults.map((info: AnimeInfo | MangaInfo) => mapId(info))); - const data = map - .filter((x) => x.success && x.data !== undefined) - .map((x) => x.data as Anime[] | Manga[]) - .flat(); - - const toInsert = data.map((x) => returnCreatedEntry(x)); - - // No need to insert since the mapId function listens to the insert event - - console.log(colors.gray("Tried to insert " + toInsert.length + " entries into the database.")); - - const end = Date.now(); - - console.log(colors.green("Finished fetching data for " + map.filter((x) => x.success).length + "/" + map.length + "anime \n Time taken: " + (end - now) + "ms")); - } catch (err) { - console.log(colors.red("Chunk failed. Fatal error.")); - console.log(err); - } - } - - console.log(colors.green("Remapping finished.")); - - async function mapId(aniData: AnimeInfo | MangaInfo) { - let isSuccess = false; - try { - const start = new Date(Date.now()); - const data = await loadMapping({ id: (aniData as any).id?.toString(), type: type }, aniData); - isSuccess = true; - - const end = new Date(Date.now()); - console.log(colors.gray("Finished fetching data. Request(s) took ") + colors.cyan(String(end.getTime() - start.getTime())) + colors.gray(" milliseconds.")); - return { id: (aniData as any).id?.toString(), success: isSuccess, data: data }; - } catch (err) { - console.log(err); - return { id: (aniData as any).id?.toString(), success: isSuccess }; - } - } -} diff --git a/anify-backend-recode/src/types/enums.ts b/anify-backend/src/types/enums.ts similarity index 100% rename from anify-backend-recode/src/types/enums.ts rename to anify-backend/src/types/enums.ts diff --git a/anify-backend-recode/src/types/types.ts b/anify-backend/src/types/types.ts similarity index 100% rename from anify-backend-recode/src/types/types.ts rename to anify-backend/src/types/types.ts diff --git a/anify-backend/src/worker/entry.ts b/anify-backend/src/worker/entry.ts deleted file mode 100644 index 275072d..0000000 --- a/anify-backend/src/worker/entry.ts +++ /dev/null @@ -1,14 +0,0 @@ -import QueueExecutor from "../helper/queue"; -import { Anime, Manga, Type } from "../mapping"; -import { createEntry } from "../lib/entry"; -import colors from "colors"; - -const executor = new QueueExecutor<{ toInsert: Anime | Manga; type: Type }>("entry-executor") - .executor(async (data) => { - const media = await createEntry(data); - return media; - }) - .callback((id) => console.debug(colors.green(`Finished creating entry for media ${id.toInsert.title.english ?? id.toInsert.title.romaji ?? id.toInsert.title.native}`))) - .error((err, id) => console.error(colors.red(`Error occurred while creating entry for media ${id.toInsert.title.english ?? id.toInsert.title.romaji ?? id.toInsert.title.native}`), err)) - .interval(500); -export default executor; diff --git a/anify-backend-recode/src/worker/impl/entry.ts b/anify-backend/src/worker/impl/entry.ts similarity index 100% rename from anify-backend-recode/src/worker/impl/entry.ts rename to anify-backend/src/worker/impl/entry.ts diff --git a/anify-backend-recode/src/worker/impl/mappings.ts b/anify-backend/src/worker/impl/mappings.ts similarity index 100% rename from anify-backend-recode/src/worker/impl/mappings.ts rename to anify-backend/src/worker/impl/mappings.ts diff --git a/anify-backend-recode/src/worker/impl/pdf.ts b/anify-backend/src/worker/impl/pdf.ts similarity index 100% rename from anify-backend-recode/src/worker/impl/pdf.ts rename to anify-backend/src/worker/impl/pdf.ts diff --git a/anify-backend-recode/src/worker/impl/search.ts b/anify-backend/src/worker/impl/search.ts similarity index 100% rename from anify-backend-recode/src/worker/impl/search.ts rename to anify-backend/src/worker/impl/search.ts diff --git a/anify-backend-recode/src/worker/impl/seasonal.ts b/anify-backend/src/worker/impl/seasonal.ts similarity index 100% rename from anify-backend-recode/src/worker/impl/seasonal.ts rename to anify-backend/src/worker/impl/seasonal.ts diff --git a/anify-backend-recode/src/worker/impl/skipTimes.ts b/anify-backend/src/worker/impl/skipTimes.ts similarity index 100% rename from anify-backend-recode/src/worker/impl/skipTimes.ts rename to anify-backend/src/worker/impl/skipTimes.ts diff --git a/anify-backend/src/worker/index.ts b/anify-backend/src/worker/index.ts index 3fd62b3..9331c6d 100644 --- a/anify-backend/src/worker/index.ts +++ b/anify-backend/src/worker/index.ts @@ -1,15 +1,15 @@ -import mappingQueue from "./mapping"; -import seasonQueue from "./season"; -import createEntry from "./entry"; -import searchQueue from "./search"; -import skipTimes from "./skipTimes"; -import uploadPages from "./upload"; +import mappingQueue from "./impl/mappings"; +import createEntry from "./impl/entry"; +import searchQueue from "./impl/search"; +import seasonalQueue from "./impl/seasonal"; +import skipTimes from "./impl/skipTimes"; +import uploadPages from "./impl/pdf"; export default { mappingQueue, - seasonQueue, createEntry, searchQueue, + seasonalQueue, skipTimes, uploadPages, }; diff --git a/anify-backend/src/worker/mapping.ts b/anify-backend/src/worker/mapping.ts deleted file mode 100644 index 6a91bfd..0000000 --- a/anify-backend/src/worker/mapping.ts +++ /dev/null @@ -1,14 +0,0 @@ -import QueueExecutor from "../helper/queue"; -import { loadMapping } from "../lib/mappings"; -import { Type } from "../mapping"; -import colors from "colors"; - -const executor = new QueueExecutor<{ id: string; type: Type }>("mapping-executor") - .executor(async (data) => { - const media = await loadMapping(data); - return media; - }) - .callback((id) => console.debug(colors.green(`Finished mapping for media ${id.id}`))) - .error((err, id) => console.error(colors.red(`Error occurred while mapping for media ${id.id}`), err)) - .interval(1000); -export default executor; diff --git a/anify-backend/src/worker/search.ts b/anify-backend/src/worker/search.ts deleted file mode 100644 index 95ab3ba..0000000 --- a/anify-backend/src/worker/search.ts +++ /dev/null @@ -1,14 +0,0 @@ -import QueueExecutor from "../helper/queue"; -import { Format, Type } from "../mapping"; -import { loadSearch } from "../lib/search"; -import colors from "colors"; - -const executor = new QueueExecutor<{ query: string; type: Type; formats: Format[] }>("search-executor") - .executor(async (data) => { - const media = await loadSearch(data); - return media; - }) - .callback((id) => console.debug(colors.green(`Finished searching for media ${id.query}.`))) - .error((err, id) => console.error(colors.red(`Error occurred while searching for media ${id.query}`), err)) - .interval(1000); -export default executor; diff --git a/anify-backend/src/worker/season.ts b/anify-backend/src/worker/season.ts deleted file mode 100644 index 512b031..0000000 --- a/anify-backend/src/worker/season.ts +++ /dev/null @@ -1,14 +0,0 @@ -import QueueExecutor from "../helper/queue"; -import { Format, Type } from "../mapping"; -import { loadSeasonal } from "../lib/season"; -import colors from "colors"; - -const executor = new QueueExecutor<{ type: Type; formats: Format[] }>("season-executor") - .executor(async (data) => { - const media = await loadSeasonal(data); - return media; - }) - .callback((id) => console.debug(colors.green(`Finished fetching seasonal data ${id.type}.`))) - .error((err, id) => console.error(colors.red(`Error occurred while fetching seasonal data ${id.type}.`), err)) - .interval(1000); -export default executor; diff --git a/anify-backend/src/worker/skipTimes.ts b/anify-backend/src/worker/skipTimes.ts deleted file mode 100644 index df0570d..0000000 --- a/anify-backend/src/worker/skipTimes.ts +++ /dev/null @@ -1,14 +0,0 @@ -import QueueExecutor from "../helper/queue"; -import colors from "colors"; -import { Source } from "../mapping/impl/anime"; -import { loadSkipTimes } from "../lib/skipTimes"; - -const executor = new QueueExecutor<{ toInsert: Source; id: string; episode: number }>("skipTimes-executor") - .executor(async (data) => { - const skipTimes = await loadSkipTimes(data); - return skipTimes; - }) - .callback((id) => console.debug(colors.green(`Finished fetching skip times for ${id.id} episode ${id.episode}.`))) - .error((err, id) => console.error(colors.red(`Error occurred while fetching skip times for ${id.id} episode ${id.episode}.`), err)) - .interval(1000); -export default executor; diff --git a/anify-backend/src/worker/upload.ts b/anify-backend/src/worker/upload.ts deleted file mode 100644 index dbddc23..0000000 --- a/anify-backend/src/worker/upload.ts +++ /dev/null @@ -1,14 +0,0 @@ -import QueueExecutor from "../helper/queue"; -import colors from "colors"; -import { Chapter, Page } from "../mapping/impl/manga"; -import { uploadPages } from "../lib/upload"; - -const executor = new QueueExecutor<{ id: string; providerId: string; chapter: Chapter; readId: string; pages: Page[] }>("page-upload-executor") - .executor(async (data) => { - const media = await uploadPages(data); - return media; - }) - .callback((id) => console.debug(colors.green(`Finished uploading pages for ${id.readId}.`))) - .error((err, id) => console.error(colors.red(`Error occurred while uploading pages for ${id.readId}`), err)) - .interval(1000); -export default executor; diff --git a/anify-backend/tsconfig.json b/anify-backend/tsconfig.json index 496bcec..388a057 100644 --- a/anify-backend/tsconfig.json +++ b/anify-backend/tsconfig.json @@ -1,28 +1,22 @@ { "compilerOptions": { - // add Bun type definitions - "types": ["bun-types"], - - // enable latest features - "lib": ["esnext"], + "lib": ["ESNext"], "module": "esnext", - "allowImportingTsExtensions": true, "target": "esnext", - - // if TS 5.x+ - "moduleResolution": "Bundler", - "noEmit": true, + "moduleResolution": "bundler", "moduleDetection": "force", - - "jsx": "react-jsx", // support JSX - "allowJs": false, // allow importing `.js` from `.ts` - "esModuleInterop": true, // allow default imports for CommonJS modules - - // best practices - "strict": false, - "forceConsistentCasingInFileNames": true, + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, "skipLibCheck": true, - "outDir": "./dist" + "jsx": "preserve", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [ + "bun-types" // add Bun global + ] } } - \ No newline at end of file diff --git a/anify-backend/yarn.lock b/anify-backend/yarn.lock deleted file mode 100644 index c84431e..0000000 --- a/anify-backend/yarn.lock +++ /dev/null @@ -1,2670 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - -"@cspotcode/source-map-support@^0.8.0": - 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== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - -"@eslint/eslintrc@^2.1.0": - version "2.1.0" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz" - integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.44.0": - version "8.44.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz" - integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== - -"@extractus/article-extractor@^8.0.2": - version "8.0.2" - resolved "https://registry.npmjs.org/@extractus/article-extractor/-/article-extractor-8.0.2.tgz" - integrity sha512-z1Kde0H6U4y8v8VbQaxaE4RliMOrVIS/KUmoRmQ7cJn9N2OPFT5K5pucRml3DCWjyEFftLmVQzJDdo3HLLMCzQ== - dependencies: - "@mozilla/readability" "^0.4.4" - bellajs "^11.1.2" - cross-fetch "^4.0.0" - linkedom "^0.15.1" - sanitize-html "2.11.0" - -"@humanwhocodes/config-array@^0.11.10": - version "0.11.10" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz" - integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@ioredis/commands@^1.1.1": - version "1.2.0" - resolved "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz" - integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@jridgewell/resolve-uri@^3.0.3": - 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== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@mozilla/readability@^0.4.4": - version "0.4.4" - resolved "https://registry.npmjs.org/@mozilla/readability/-/readability-0.4.4.tgz" - integrity sha512-MCgZyANpJ6msfvVMi6+A0UAsvZj//4OHREYUB9f2087uXHVoU+H+SWhuihvb1beKpM323bReQPRio0WNk2+V6g== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@oven/bun-darwin-aarch64@0.8.1": - version "0.8.1" - resolved "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-0.8.1.tgz" - integrity sha512-rdZ4vqDckP/vKjpz5TIEcj45KxIizS6k5dYO6KUOu2nlMwy+JRAE1wfrKY8qAelQ+nE96VYurD8BjkgKQiR4Iw== - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@prisma/client@^4.15.0": - version "4.15.0" - resolved "https://registry.npmjs.org/@prisma/client/-/client-4.15.0.tgz" - integrity sha512-xnROvyABcGiwqRNdrObHVZkD9EjkJYHOmVdlKy1yGgI+XOzvMzJ4tRg3dz1pUlsyhKxXGCnjIQjWW+2ur+YXuw== - dependencies: - "@prisma/engines-version" "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944" - -"@prisma/debug@4.13.0": - version "4.13.0" - resolved "https://registry.npmjs.org/@prisma/debug/-/debug-4.13.0.tgz" - integrity sha512-JrltTewF/paRb5mcM5OvcEi9DtdX0sINOAswruxKQrwOLA7Phqb52OfY38MIzGrsrJ8iUGVqQ5bpYZYpxOGCsQ== - dependencies: - "@types/debug" "4.1.7" - debug "4.3.4" - strip-ansi "6.0.1" - -"@prisma/engines-version@4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944": - version "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944" - resolved "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944.tgz" - integrity sha512-sVOig4tjGxxlYaFcXgE71f/rtFhzyYrfyfNFUsxCIEJyVKU9rdOWIlIwQ2NQ7PntvGnn+x0XuFo4OC1jvPJKzg== - -"@prisma/engines@5.0.0": - version "5.0.0" - resolved "https://registry.npmjs.org/@prisma/engines/-/engines-5.0.0.tgz" - integrity sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg== - -"@prisma/generator-helper@^4.10.1": - version "4.13.0" - resolved "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.13.0.tgz" - integrity sha512-Zx9rtbsEIU/9DKnGRvmjLdyeyhzeeXNFp1alkRh1w//rQ5jTcobiay/jU4Qo+EQOs2bnWEfUeiBoOjfaysdLNg== - dependencies: - "@prisma/debug" "4.13.0" - "@types/cross-spawn" "6.0.2" - chalk "4.1.2" - cross-spawn "7.0.3" - -"@swc/helpers@^0.3.13": - version "0.3.17" - resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.3.17.tgz" - integrity sha512-tb7Iu+oZ+zWJZ3HJqwx8oNwSDIU440hmVMDPhpACWQWnrZHK99Bxs70gT1L2dnr5Hg50ZRWEFkQCAnOVVV0z1Q== - dependencies: - tslib "^2.4.0" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== - -"@types/cross-spawn@6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz" - integrity sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw== - dependencies: - "@types/node" "*" - -"@types/debug@4.1.7": - version "4.1.7" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== - dependencies: - "@types/ms" "*" - -"@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/ms@*": - version "0.7.31" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/needle@*": - version "3.2.0" - resolved "https://registry.npmjs.org/@types/needle/-/needle-3.2.0.tgz" - integrity sha512-6XzvzEyJ2ozFNfPajFmqH9JOt0Hp+9TawaYpJT59iIP/zR0U37cfWCRwosyIeEBBZBi021Osq4jGAD3AOju5fg== - dependencies: - "@types/node" "*" - -"@types/node@*", "@types/node@^18.16.16": - version "18.16.16" - resolved "https://registry.npmjs.org/@types/node/-/node-18.16.16.tgz" - integrity sha512-NpaM49IGQQAUlBhHMF82QH80J08os4ZmyF9MkpCzWAGuOHqE4gTEbhzd7L3l5LmWuZ6E0OiC1FweQ4tsiW35+g== - -"@types/pdfkit@^0.12.10": - version "0.12.10" - resolved "https://registry.npmjs.org/@types/pdfkit/-/pdfkit-0.12.10.tgz" - integrity sha512-DPqNCuLXj50NehiFehndH+fzQLzb2fwHOLOvG+Zsm7rJBHgpMLeJrB4eC3RQf7Zl1uiWVYyBuFqVbZnveUb4mA== - dependencies: - "@types/node" "*" - -"@types/probe-image-size@^7.2.0": - version "7.2.0" - resolved "https://registry.npmjs.org/@types/probe-image-size/-/probe-image-size-7.2.0.tgz" - integrity sha512-R5H3vw62gHNHrn+JGZbKejb+Z2D/6E5UNVlhCzIaBBLroMQMOFqy5Pap2gM+ZZHdqBtVU0/cx/M6to+mOJcoew== - dependencies: - "@types/needle" "*" - "@types/node" "*" - -"@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@typescript-eslint/eslint-plugin@^5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz" - integrity sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/type-utils" "5.59.8" - "@typescript-eslint/utils" "5.59.8" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz" - integrity sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw== - dependencies: - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/typescript-estree" "5.59.8" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz" - integrity sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig== - dependencies: - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/visitor-keys" "5.59.8" - -"@typescript-eslint/type-utils@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz" - integrity sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA== - dependencies: - "@typescript-eslint/typescript-estree" "5.59.8" - "@typescript-eslint/utils" "5.59.8" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz" - integrity sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w== - -"@typescript-eslint/typescript-estree@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz" - integrity sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg== - dependencies: - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/visitor-keys" "5.59.8" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz" - integrity sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/typescript-estree" "5.59.8" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz" - integrity sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ== - dependencies: - "@typescript-eslint/types" "5.59.8" - eslint-visitor-keys "^3.3.0" - -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.4.1, acorn@^8.9.0: - version "8.9.0" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz" - integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-js@^1.1.2, base64-js@^1.3.0: - version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -base64-js@0.0.8: - version "0.0.8" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz" - integrity sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw== - -bellajs@^11.1.2: - version "11.1.2" - resolved "https://registry.npmjs.org/bellajs/-/bellajs-11.1.2.tgz" - integrity sha512-2Fy3Km5JKyIy/KunW3oica2gZtkjD2qSqti2Q3xPhHvXXdMbc+32pEMOPG+xrSat0BXVhRjHIx++lzxIPK0GqQ== - -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brotli@^1.3.2: - version "1.3.3" - resolved "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz" - integrity sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg== - dependencies: - base64-js "^1.1.2" - -bun-types@^0.8.1: - version "0.8.1" - resolved "https://registry.npmjs.org/bun-types/-/bun-types-0.8.1.tgz" - integrity sha512-VuCBox66P/3a8gVOffLCWIS6vdpXq4y3eJuF3VnsyC5HpykmIjkcr5wYDn22qQdeTUmOfCcBy1SZmtrZCeUr3A== - -bun@^0.8.1: - version "0.8.1" - resolved "https://registry.npmjs.org/bun/-/bun-0.8.1.tgz" - integrity sha512-bWVEO9ipiG00dSOtCd/iGZ+LyxuO8l1SBE9uExg/npUQpC0B/ZQlK3whnV05grOd5gQ0wY4oxO75Csdt+g3VZA== - optionalDependencies: - "@oven/bun-darwin-aarch64" "0.8.1" - "@oven/bun-darwin-x64" "0.8.1" - "@oven/bun-darwin-x64-baseline" "0.8.1" - "@oven/bun-linux-aarch64" "0.8.1" - "@oven/bun-linux-x64" "0.8.1" - "@oven/bun-linux-x64-baseline" "0.8.1" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -chalk@^4.0.0, chalk@4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -cheerio-select@^2.1.0: - version "2.1.0" - 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" - css-what "^6.1.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - -cheerio@1.0.0-rc.12: - version "1.0.0-rc.12" - 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" - domhandler "^5.0.3" - domutils "^3.0.1" - htmlparser2 "^8.0.1" - parse5 "^7.0.0" - parse5-htmlparser2-tree-adapter "^7.0.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz" - integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== - -cluster-key-slot@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz" - integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colors@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - -copyfiles@^2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz" - integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg== - dependencies: - glob "^7.0.5" - minimatch "^3.0.3" - mkdirp "^1.0.4" - noms "0.0.0" - through2 "^2.0.1" - untildify "^4.0.0" - yargs "^16.1.0" - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-fetch@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz" - integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== - dependencies: - node-fetch "^2.6.12" - -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-js@^4.0.0, crypto-js@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz" - integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== - -css-select@^5.1.0: - version "5.1.0" - 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" - domhandler "^5.0.2" - domutils "^3.0.1" - nth-check "^2.0.1" - -css-what@^6.1.0: - version "6.1.0" - resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - -cssom@^0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz" - integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== - -debug@^3.2.6: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@2: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -deep-equal@^2.0.5: - version "2.2.2" - resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz" - integrity sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - es-get-iterator "^1.1.3" - get-intrinsic "^1.2.1" - is-arguments "^1.1.1" - is-array-buffer "^3.0.2" - is-date-object "^1.0.5" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - isarray "^2.0.5" - object-is "^1.1.5" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.0" - side-channel "^1.0.4" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" - -deep-is@^0.1.3: - 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== - -deepmerge@^4.2.2: - 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== - -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -denque@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz" - integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -dfa@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz" - integrity sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-serializer@^2.0.0: - version "2.0.0" - 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" - entities "^4.2.0" - -domelementtype@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: - version "5.0.3" - resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" - integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== - dependencies: - domelementtype "^2.3.0" - -domutils@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz" - integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== - dependencies: - dom-serializer "^2.0.0" - domelementtype "^2.3.0" - domhandler "^5.0.1" - -dotenv@^16.1.4: - version "16.1.4" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz" - integrity sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw== - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -entities@^4.2.0, entities@^4.4.0: - version "4.5.0" - resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" - integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== - -es-get-iterator@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz" - integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - has-symbols "^1.0.3" - is-arguments "^1.1.1" - is-map "^2.0.2" - is-set "^2.0.2" - is-string "^1.0.7" - isarray "^2.0.5" - stop-iteration-iterator "^1.0.0" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint@*, "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", eslint@^8.45.0: - version "8.45.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz" - integrity sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.1.0" - "@eslint/js" "8.44.0" - "@humanwhocodes/config-array" "^0.11.10" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.6.0" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -espree@^9.6.0: - version "9.6.0" - resolved "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz" - integrity sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -eventemitter2@^6.4.9: - version "6.4.9" - resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz" - integrity sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg== - -express-rate-limit@^6: - version "6.7.0" - resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.7.0.tgz" - integrity sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA== - -"express@^4 || ^5": - version "4.18.2" - resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.1" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.11.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - 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== - -fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - 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" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -fontkit@^1.8.1: - version "1.9.0" - resolved "https://registry.npmjs.org/fontkit/-/fontkit-1.9.0.tgz" - integrity sha512-HkW/8Lrk8jl18kzQHvAw9aTHe1cqsyx5sDnxncx652+CIfhawokEPkeM3BoIC+z/Xv7a0yMr0f3pRRwhGH455g== - dependencies: - "@swc/helpers" "^0.3.13" - brotli "^1.3.2" - clone "^2.1.2" - deep-equal "^2.0.5" - dfa "^1.2.0" - restructure "^2.0.1" - tiny-inflate "^1.0.3" - unicode-properties "^1.3.1" - unicode-trie "^2.0.0" - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - -form-data@^4.0.0: - version "4.0.0" - 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" - mime-types "^2.1.12" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@^10.2.5: - version "10.2.6" - resolved "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz" - integrity sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.0.3" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2" - path-scurry "^1.7.0" - -glob@^7.0.5, glob@^7.1.3: - version "7.1.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - 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" - -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - 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" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -has-bigints@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-proto@^1.0.1: - 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== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -html-escaper@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz" - integrity sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ== - -htmlparser2@^8.0.0, htmlparser2@^8.0.1: - version "8.0.2" - resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz" - integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - entities "^4.4.0" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -iconv-lite@^0.4.4, iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - 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" - -inherits@^2.0.1, inherits@~2.0.1, inherits@~2.0.3, inherits@2, inherits@2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -internal-slot@^1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== - dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" - side-channel "^1.0.4" - -ioredis@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz" - integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== - dependencies: - "@ioredis/commands" "^1.1.1" - cluster-key-slot "^1.1.0" - debug "^4.3.4" - denque "^2.1.0" - lodash.defaults "^4.2.0" - lodash.isarguments "^3.1.0" - redis-errors "^1.2.0" - redis-parser "^3.0.0" - standard-as-callback "^2.1.0" - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-arguments@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.3: - version "1.2.7" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-date-object@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - 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== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-map@^2.0.1, is-map@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - 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== - -is-plain-object@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-set@^2.0.1, is-set@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== - -is-shared-array-buffer@^1.0.2: - 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== - dependencies: - call-bind "^1.0.2" - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10: - version "1.1.12" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - -is-weakset@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" - integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -jackspeak@^2.0.3: - version "2.2.1" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz" - integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -linebreak@^1.0.2: - version "1.1.0" - resolved "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz" - integrity sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ== - dependencies: - base64-js "0.0.8" - unicode-trie "^2.0.0" - -linkedom@^0.15.1: - version "0.15.3" - resolved "https://registry.npmjs.org/linkedom/-/linkedom-0.15.3.tgz" - integrity sha512-p+lBSEWzawF3Gy7+nw+5+u+iDthsfZZVd9lwiO96Ihj7Zd8he5BD1Wzdc9Z4GqtU6lKvxhye4W4Zr20uOAGe4A== - dependencies: - css-select "^5.1.0" - cssom "^0.5.0" - html-escaper "^3.0.3" - htmlparser2 "^8.0.1" - uhyphen "^0.2.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz" - integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== - -lodash.isarguments@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz" - integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lru-cache@^6.0.0: - 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" - -lru-cache@^9.1.1: - version "9.1.2" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz" - integrity sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ== - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - 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" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: - 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" - -minimatch@^9.0.1: - version "9.0.1" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz" - integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== - dependencies: - brace-expansion "^2.0.1" - -"minipass@^5.0.0 || ^6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== - -mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -ms@^2.1.1, ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -nanoid@^3.3.6: - version "3.3.6" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -needle@^2.5.2: - version "2.9.1" - resolved "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz" - integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -node-fetch@^2.6.12: - version "2.7.0" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -noms@0.0.0: - version "0.0.0" - resolved "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz" - integrity sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow== - dependencies: - inherits "^2.0.1" - readable-stream "~1.0.31" - -nth-check@^2.0.1: - version "2.1.1" - 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" - -object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== - -object-is@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -once@^1.3.0: - 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" - -optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - 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== - dependencies: - p-limit "^3.0.2" - -pako@^0.2.5: - version "0.2.9" - resolved "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz" - integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA== - -parent-module@^1.0.0: - 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== - dependencies: - callsites "^3.0.0" - -parse-srcset@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz" - integrity sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q== - -parse5-htmlparser2-tree-adapter@^7.0.0: - version "7.0.0" - 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" - -parse5@^7.0.0: - version "7.1.2" - resolved "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz" - integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== - dependencies: - entities "^4.4.0" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-scurry@^1.7.0: - version "1.9.2" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz" - integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg== - dependencies: - lru-cache "^9.1.1" - minipass "^5.0.0 || ^6.0.2" - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pdfkit@^0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/pdfkit/-/pdfkit-0.13.0.tgz" - integrity sha512-AW79eHU5eLd2vgRDS9z3bSoi0FA+gYm+100LLosrQQMLUzOBGVOhG7ABcMFpJu7Bpg+MT74XYHi4k9EuU/9EZw== - dependencies: - crypto-js "^4.0.0" - fontkit "^1.8.1" - linebreak "^1.0.2" - png-js "^1.0.0" - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -png-js@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz" - integrity sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g== - -postcss@^8.3.11: - version "8.4.29" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz" - integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw== - dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier@2.8.8: - version "2.8.8" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -prisma-json-types-generator@^2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-2.4.0.tgz" - integrity sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg== - dependencies: - "@prisma/generator-helper" "^4.10.1" - tslib "^2.5.0" - -prisma@*, prisma@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/prisma/-/prisma-5.0.0.tgz" - integrity sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA== - dependencies: - "@prisma/engines" "5.0.0" - -probe-image-size@^7.2.3: - version "7.2.3" - resolved "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.2.3.tgz" - integrity sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w== - dependencies: - lodash.merge "^4.6.2" - needle "^2.5.2" - stream-parser "~0.3.1" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -qs@6.11.0: - version "6.11.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -rate-limit-redis@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-3.0.2.tgz" - integrity sha512-4SBK6AzIr9PKkCF4HmSDcJH2O2KKMF3fZEcsbNMXyaL5I9d6X71uOreUldFRiyrRyP+qkQrTxzJ38ZKKN+sScw== - -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -readable-stream@~1.0.31: - version "1.0.34" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" - integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@~2.3.6: - version "2.3.8" - 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" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -redis-errors@^1.0.0, redis-errors@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz" - integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== - -redis-parser@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz" - integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== - dependencies: - redis-errors "^1.0.0" - -regexp.prototype.flags@^1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz" - integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - functions-have-names "^1.2.3" - -require-directory@^2.1.1: - 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== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -restructure@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/restructure/-/restructure-2.0.1.tgz" - integrity sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rimraf@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz" - integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== - dependencies: - glob "^10.2.5" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sanitize-html@2.11.0: - version "2.11.0" - resolved "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.11.0.tgz" - integrity sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA== - dependencies: - deepmerge "^4.2.2" - escape-string-regexp "^4.0.0" - htmlparser2 "^8.0.0" - is-plain-object "^5.0.0" - parse-srcset "^1.0.2" - postcss "^8.3.11" - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -semver@^7.3.7: - version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -send@0.18.0: - version "0.18.0" - resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz" - integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - -standard-as-callback@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz" - integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -stop-iteration-iterator@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" - integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== - dependencies: - internal-slot "^1.0.4" - -stream-parser@~0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz" - integrity sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ== - dependencies: - debug "2" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - -string_decoder@~1.1.1: - version "1.1.1" - 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" - -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1, strip-ansi@6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-json-comments@^3.1.1: - 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== - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -through2@^2.0.1: - version "2.0.5" - resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -tiny-inflate@^1.0.0, tiny-inflate@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz" - integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== - -to-regex-range@^5.0.1: - 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== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -ts-node@^10.9.1: - version "10.9.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - 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" - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.4.0, tslib@^2.5.0, tslib@^2.5.3: - version "2.5.3" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz" - integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.20.2: - 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== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typescript@^5.2.2, typescript@>=2.7, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": - version "5.2.2" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz" - integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== - -uhyphen@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz" - integrity sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA== - -unicode-properties@^1.3.1: - version "1.4.1" - resolved "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz" - integrity sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg== - dependencies: - base64-js "^1.3.0" - unicode-trie "^2.0.0" - -unicode-trie@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz" - integrity sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ== - dependencies: - pako "^0.2.5" - tiny-inflate "^1.0.0" - -unpipe@~1.0.0, unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -v8-compile-cache-lib@^3.0.1: - 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== - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - 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" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - -which-typed-array@^1.1.11, which-typed-array@^1.1.9: - version "1.1.11" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz" - integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs@^16.1.0: - version "16.2.0" - resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx b/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx index 56c1fdd..2a03ac9 100644 --- a/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx +++ b/anify-frontend/src/pages/read/[id]/[provider]/[readId].tsx @@ -603,9 +603,9 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const pages = await (await axios.post(String(env.BACKEND_URL) + "/pages?apikey=" + String(env.API_KEY), { chapterNumber, - chapterTitle, providerId: provider, - readId + readId, + id })).data as Page[]; if (media.format !== "NOVEL") { From 958367da8b51667c0d109fafc24cacbb620cf338 Mon Sep 17 00:00:00 2001 From: Eltik Date: Tue, 12 Sep 2023 13:38:36 -0400 Subject: [PATCH 31/77] Added recode for manager --- anify-backend/package.json | 3 +- anify-backend/src/mappings/impl/base/index.ts | 2 +- anify-manager-recode/.eslintignore | 2 + anify-manager-recode/.eslintrc | 33 ++++ anify-manager-recode/.gitignore | 169 ++++++++++++++++++ anify-manager-recode/.prettierignore | 12 ++ anify-manager-recode/.prettierrc.json | 13 ++ anify-manager-recode/README.md | 15 ++ anify-manager-recode/package.json | 27 +++ anify-manager-recode/src/config.ts | 24 +++ anify-manager-recode/src/discord/client.ts | 129 +++++++++++++ .../src/discord/commands/anify/list.ts | 18 ++ .../src/discord/commands/anify/pull.ts | 30 ++++ anify-manager-recode/src/discord/responses.ts | 69 +++++++ .../src/discord/responses/anify.ts | 132 ++++++++++++++ anify-manager-recode/src/discord/types.d.ts | 1 + anify-manager-recode/src/env.ts | 6 + anify-manager-recode/src/index.ts | 1 + anify-manager-recode/src/utils/fs/health.ts | 93 ++++++++++ anify-manager-recode/src/utils/fs/view.ts | 27 +++ anify-manager-recode/src/utils/pm2/build.ts | 95 ++++++++++ anify-manager-recode/src/utils/pm2/index.ts | 7 + .../src/utils/pm2/initalizePm2.ts | 17 ++ anify-manager-recode/src/utils/pm2/kill.ts | 32 ++++ anify-manager-recode/src/utils/pm2/list.ts | 27 +++ anify-manager-recode/src/utils/pm2/run.ts | 50 ++++++ anify-manager-recode/src/utils/pm2/update.ts | 143 +++++++++++++++ anify-manager-recode/tsconfig.json | 22 +++ 28 files changed, 1197 insertions(+), 2 deletions(-) create mode 100644 anify-manager-recode/.eslintignore create mode 100644 anify-manager-recode/.eslintrc create mode 100644 anify-manager-recode/.gitignore create mode 100644 anify-manager-recode/.prettierignore create mode 100644 anify-manager-recode/.prettierrc.json create mode 100644 anify-manager-recode/README.md create mode 100644 anify-manager-recode/package.json create mode 100644 anify-manager-recode/src/config.ts create mode 100644 anify-manager-recode/src/discord/client.ts create mode 100644 anify-manager-recode/src/discord/commands/anify/list.ts create mode 100644 anify-manager-recode/src/discord/commands/anify/pull.ts create mode 100644 anify-manager-recode/src/discord/responses.ts create mode 100644 anify-manager-recode/src/discord/responses/anify.ts create mode 100644 anify-manager-recode/src/discord/types.d.ts create mode 100644 anify-manager-recode/src/env.ts create mode 100644 anify-manager-recode/src/index.ts create mode 100644 anify-manager-recode/src/utils/fs/health.ts create mode 100644 anify-manager-recode/src/utils/fs/view.ts create mode 100644 anify-manager-recode/src/utils/pm2/build.ts create mode 100644 anify-manager-recode/src/utils/pm2/index.ts create mode 100644 anify-manager-recode/src/utils/pm2/initalizePm2.ts create mode 100644 anify-manager-recode/src/utils/pm2/kill.ts create mode 100644 anify-manager-recode/src/utils/pm2/list.ts create mode 100644 anify-manager-recode/src/utils/pm2/run.ts create mode 100644 anify-manager-recode/src/utils/pm2/update.ts create mode 100644 anify-manager-recode/tsconfig.json diff --git a/anify-backend/package.json b/anify-backend/package.json index 4b6355f..f64e1cc 100644 --- a/anify-backend/package.json +++ b/anify-backend/package.json @@ -1,5 +1,6 @@ { - "name": "test", + "name": "anify-backend", + "description": "Anify Backend", "module": "index.ts", "type": "module", "scripts": { diff --git a/anify-backend/src/mappings/impl/base/index.ts b/anify-backend/src/mappings/impl/base/index.ts index b6587c3..a6211fb 100644 --- a/anify-backend/src/mappings/impl/base/index.ts +++ b/anify-backend/src/mappings/impl/base/index.ts @@ -31,7 +31,7 @@ export default abstract class BaseProvider { return undefined; } - async fetchSchedule(): Promise { + async fetchIds(): Promise { return undefined; } diff --git a/anify-manager-recode/.eslintignore b/anify-manager-recode/.eslintignore new file mode 100644 index 0000000..7d671e7 --- /dev/null +++ b/anify-manager-recode/.eslintignore @@ -0,0 +1,2 @@ +/dist +**/*.js \ No newline at end of file diff --git a/anify-manager-recode/.eslintrc b/anify-manager-recode/.eslintrc new file mode 100644 index 0000000..13b5ac5 --- /dev/null +++ b/anify-manager-recode/.eslintrc @@ -0,0 +1,33 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@typescript-eslint/ban-types": "warn", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-loss-of-precision": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-non-null-asserted-optional-chain": "off", + "@typescript-eslint/no-unnecessary-type-constraint": "warn", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-var-requires": "warn", + "no-console": "off", + "no-empty": "warn", + "no-prototype-builtins": "off", + "no-redeclare": "warn", + "no-useless-escape": "off", + "no-async-promise-executor": "off", + "prefer-const": "warn", + "array-bracket-spacing": ["error", "never"] + } +} \ No newline at end of file diff --git a/anify-manager-recode/.gitignore b/anify-manager-recode/.gitignore new file mode 100644 index 0000000..f81d56e --- /dev/null +++ b/anify-manager-recode/.gitignore @@ -0,0 +1,169 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +\*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +\*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +\*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +\*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.cache +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +.cache/ + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp +.cache + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.\* diff --git a/anify-manager-recode/.prettierignore b/anify-manager-recode/.prettierignore new file mode 100644 index 0000000..eeda442 --- /dev/null +++ b/anify-manager-recode/.prettierignore @@ -0,0 +1,12 @@ +node_modules +*.js +*.d.ts +*.md +*.json +*.lock +*.yml +*.yaml +Dockerfile +Dockerfile.* +.eslintrc +*.html \ No newline at end of file diff --git a/anify-manager-recode/.prettierrc.json b/anify-manager-recode/.prettierrc.json new file mode 100644 index 0000000..0e41e21 --- /dev/null +++ b/anify-manager-recode/.prettierrc.json @@ -0,0 +1,13 @@ +{ + "useTabs": false, + "tabWidth": 4, + "semi": true, + "singleQuote": false, + "bracketSpacing": true, + "bracketSameLine": false, + "arrowParens": "always", + "parser": "typescript", + "printWidth": 10000, + "proseWrap": "never", + "endOfLine": "lf" +} diff --git a/anify-manager-recode/README.md b/anify-manager-recode/README.md new file mode 100644 index 0000000..050d6e2 --- /dev/null +++ b/anify-manager-recode/README.md @@ -0,0 +1,15 @@ +# anify-manager-recode + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +``` + +This project was created using `bun init` in bun v1.0.0. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/anify-manager-recode/package.json b/anify-manager-recode/package.json new file mode 100644 index 0000000..102bc54 --- /dev/null +++ b/anify-manager-recode/package.json @@ -0,0 +1,27 @@ +{ + "name": "anify-manager-recode", + "module": "index.ts", + "type": "module", + "scripts": { + "start": "bun run dist/index.js", + "dev": "bun run src/index.ts", + "build": "bun build ./src/index.ts --outdir ./dist --target node", + "prettier": "prettier --write .", + "eslint": "eslint --ext .ts src/** --fix", + "lint": "bun run prettier && bun run eslint" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^6.7.0", + "@typescript-eslint/parser": "^6.7.0", + "bun-types": "latest", + "eslint": "^8.49.0" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "colors": "^1.4.0", + "eris": "^0.17.2", + "pm2": "^5.3.0" + } +} \ No newline at end of file diff --git a/anify-manager-recode/src/config.ts b/anify-manager-recode/src/config.ts new file mode 100644 index 0000000..d6fea22 --- /dev/null +++ b/anify-manager-recode/src/config.ts @@ -0,0 +1,24 @@ +export const buildCommands: { + [key: string]: { + command: string; + ".env"?: string; + }; +} = { + anify: { + command: "npm run build", + ".env": `.env`, + }, +}; + +export const runCommands: { + [key: string]: string; +} = { + anify: "npm run i", +}; + +export const repositories = [ + { + url: "https://github.com/Eltik/Anify", + name: "anify", + }, +]; diff --git a/anify-manager-recode/src/discord/client.ts b/anify-manager-recode/src/discord/client.ts new file mode 100644 index 0000000..62118a6 --- /dev/null +++ b/anify-manager-recode/src/discord/client.ts @@ -0,0 +1,129 @@ +import Eris from "eris/esm"; +import colors from "colors"; +import { env } from "../env"; +import { lstatSync, readdirSync } from "fs"; +import { join } from "path"; +import { ApplicationCommand, AutocompleteInteraction, Client, CommandInteraction, ComponentInteraction } from "eris"; + +export interface CustomClient extends Client { + commands: Map; +} + +const client = Eris(env.DISCORD_TOKEN ?? "", { + intents: [], +}) as CustomClient; +client.commands = new Map(); + +const subCommandNaming = (parent: string, child: string) => `${parent}-${child}`.toLowerCase(); + +const createSubCommand = (name: string, description: string, command: ApplicationCommand[]) => { + return { + type: 1, + name, + description, + options: command.map((x) => ({ + ...x, + type: 1, + })), + }; +}; + +client.on("ready", async () => { + console.log(colors.green("Bot is ready!")); + + const commands = await client.getCommands(); + if (commands.length) return; + + client.createCommand = (command: ApplicationCommand) => { + return client.createGuildCommand(env.GUILD_ID ?? "", command); + }; + + client.bulkEditCommands = (commands: ApplicationCommand[]) => { + return client.bulkEditGuildCommands(env.GUILD_ID ?? "", commands); + }; + + // launch all commands from commands folder + readdirSync(join(import.meta.dir, "./commands")).forEach((file) => { + // check if file is a folder (if it is make it a subcommand) + if (lstatSync(join(import.meta.dir, `./commands/${file}`)).isDirectory()) { + let subcommands: ApplicationCommand[] = []; + readdirSync(join(import.meta.dir, `./commands/${file}`)).forEach((subfile) => { + const command = require(`./commands/${file}/${subfile}`).default; + if (command.setup) { + command.setup(client); + client.commands.set(command.name, command); + + console.log(colors.gray(`Loaded command ${file}/${subfile} ${command.name}`)); + } else { + subcommands.push(command.schema); + client.commands.set(subCommandNaming(file, command.name), command); + } + }); + + const command = createSubCommand(file, "Subcommand", subcommands); + client.createCommand(command as any); + return; + } + + const command = require(`./commands/${file}`).default; + command.setup(client); + client.commands.set(command.name, command); + console.log(`Loaded command ${file} ${command.name}`); + }); +}); + +client.on("interactionCreate", async (interaction) => { + if (interaction instanceof ComponentInteraction) { + if (!interaction.member?.roles.includes(env.ADMIN_ROLE_ID ?? "")) return; + + const message = await client.getMessage(interaction.message.channel.id, interaction.message.id); + let posibleName: string[] = []; + message.referencedMessage?.components?.forEach((x) => { + x.components.map((y) => { + if ("custom_id" in y) { + posibleName.push(y.custom_id); + } + }); + }); + + let name = posibleName[0] || interaction?.message?.interaction?.name.split(" ").join("-").toLowerCase() || interaction.data.custom_id.split(" ").join("-").toLowerCase(); + + if (client.commands.has(name)) return client.commands.get(name).onInteraction(client, interaction); + } + + if (interaction instanceof AutocompleteInteraction) { + if (!interaction.member?.roles.includes(env.ADMIN_ROLE_ID ?? "")) return; + + let name = interaction.data.name; + if (interaction.data.options && interaction.data.options[0].type === 1) { + name = subCommandNaming(name, interaction.data.options[0].name); + } + + if (client.commands.has(name)) return client.commands.get(name).autocomplete(client, interaction); + } + + if (interaction instanceof CommandInteraction) { + // check if the command required admin role + if (!interaction.member?.roles.includes(env.ADMIN_ROLE_ID ?? "")) return; + + let name = interaction.data.name; + if (interaction.data.options && interaction.data.options[0].type === 1) { + name = subCommandNaming(name, interaction.data.options[0].name); + } + + if (client.commands.has(name)) return client.commands.get(name).on(client, interaction); + switch (interaction.data.name) { + case "ping": + return interaction.createMessage(`Pong!`); + default: { + return interaction.createMessage("interaction recieved: " + interaction.data.name); + } + } + } +}); + +client.on("error", (err: Error) => { + console.error(err); +}); + +client.connect().catch(console.error); diff --git a/anify-manager-recode/src/discord/commands/anify/list.ts b/anify-manager-recode/src/discord/commands/anify/list.ts new file mode 100644 index 0000000..d8ed365 --- /dev/null +++ b/anify-manager-recode/src/discord/commands/anify/list.ts @@ -0,0 +1,18 @@ +import * as response from "../../responses/anify"; +import view from "../../../utils/fs/view"; +import { Client, CommandInteraction, Constants, TextableChannel } from "eris"; + +export default { + name: "list", + schema: { + name: "list", + description: "View all the folders in the build folder. (This is where the repos are stored.)", + type: Constants.ApplicationCommandTypes.CHAT_INPUT, + }, + on: async (client: Client, interaction: CommandInteraction) => { + const folders = view(); + if (!folders.length || !folders) return interaction.createMessage(response.listRepo.error.message("Cant find any folders in build folder!")); + + interaction.createMessage(response.listRepo.message(folders)); + }, +}; diff --git a/anify-manager-recode/src/discord/commands/anify/pull.ts b/anify-manager-recode/src/discord/commands/anify/pull.ts new file mode 100644 index 0000000..45afa8e --- /dev/null +++ b/anify-manager-recode/src/discord/commands/anify/pull.ts @@ -0,0 +1,30 @@ +import * as response from "../../responses/anify"; +import { build } from "../../../utils/pm2"; +import { Client, CommandInteraction, Constants, TextableChannel } from "eris"; + +export default { + name: "pull", + schema: { + name: "pull", + description: "pull the latest repos from github under the folder label.", + type: Constants.ApplicationCommandTypes.CHAT_INPUT, + options: [ + { + name: "label", + description: "the label of the folder which the latest repos will be in.", + type: Constants.ApplicationCommandOptionTypes.STRING, + required: true, + }, + ], + }, + on: async (client: Client, interaction: CommandInteraction) => { + let value = (interaction?.data?.options?.[0] as any)?.options?.[0]?.value as string; + + if (!interaction.acknowledged) await interaction.acknowledge(1); + + const data = await build(value, ["anify"], 0); + console.log(data); + + interaction.editOriginalMessage(response.run.error.message(JSON.stringify(data))); + }, +}; diff --git a/anify-manager-recode/src/discord/responses.ts b/anify-manager-recode/src/discord/responses.ts new file mode 100644 index 0000000..93410e0 --- /dev/null +++ b/anify-manager-recode/src/discord/responses.ts @@ -0,0 +1,69 @@ +import { ActionRow, EmbedOptions, InteractionContent } from "eris"; +import Eris from "eris/esm"; + +export interface CustomError { + embeds: (reason: string) => EmbedOptions[]; + message: (reason: string) => InteractionContent; +} + +interface NotImplemented { + embeds: () => EmbedOptions[]; + message: () => InteractionContent; +} + +export interface customEmbed { + embeds: (arg0: T) => EmbedOptions[]; + components?: (arg0: T) => ActionRow[]; + message: (arg0: T) => InteractionContent; + error: CustomError; +} + +export function createCustomEmbed(options?: Partial>): customEmbed { + const custom: customEmbed = { + embeds: options?.embeds ?? notImplemented.embeds, + components: options?.components ?? undefined, + message: + options?.message ?? + ((arg0: T) => ({ + embeds: custom.embeds(arg0), + components: custom.components ? custom.components(arg0) : undefined, + })), + error: options?.error ?? error, + }; + return custom; +} + +export const error: CustomError = { + embeds: (reason) => { + return [ + { + title: "Error Occurred!", + color: 0xff0000, + description: `${reason}`, + }, + ]; + }, + message: (reason) => { + return { + embeds: error.embeds(reason), + components: [], + }; + }, +}; + +export const notImplemented: NotImplemented = { + embeds: () => { + return [ + { + title: "Not Implemented!", + color: 0xff0000, + description: `This command is not implemented yet!`, + }, + ]; + }, + message: () => { + return { + embeds: notImplemented.embeds(), + }; + }, +}; diff --git a/anify-manager-recode/src/discord/responses/anify.ts b/anify-manager-recode/src/discord/responses/anify.ts new file mode 100644 index 0000000..fb63383 --- /dev/null +++ b/anify-manager-recode/src/discord/responses/anify.ts @@ -0,0 +1,132 @@ +import { createCustomEmbed, customEmbed, error, notImplemented } from "../responses"; +import { Stats } from "fs"; + +export const update: customEmbed<{ + data: { + [key: string]: string; + }[]; +}> = createCustomEmbed({ + embeds: ({ data }) => { + return [ + { + title: "Updated", + fields: data.map((x) => ({ + name: Object.keys(x)[0], + value: x[Object.keys(x)[0]], + })), + }, + ]; + }, +}); + +export const run: customEmbed< + { + error?: string; + data?: string; + }[] +> = createCustomEmbed({ + embeds: (repos) => [ + { + title: repos.map((x) => (x.error ? `${x.error} - ${x.data}` : `Started ${x.data}`)).join("\n"), + }, + ], + components: () => [ + { + type: 1, + components: [ + { + type: 2, + label: `view running processes`, + emoji: { + id: "1108981152431226891", + }, + style: 1, + custom_id: "kato-running", + }, + ], + }, + ], +}); + +export const viewRunningRepo: customEmbed = createCustomEmbed({ + embeds: (repos) => [ + { + title: "Select a repository", + fields: repos.map((x) => ({ + name: x, + value: `Click the ${x} below to **KILL** the pm2 process`, + })), + }, + ], + components: (repos) => [ + { + type: 1, + components: repos.map((x) => ({ + type: 2, + label: `${x}`, + emoji: { + id: "1108981152431226891", + }, + style: 4, + custom_id: x, + })), + }, + ], + error: { + embeds: error.embeds, + message: (reason) => ({ + embeds: error.embeds(reason), + components: [ + { + type: 1, + components: [ + { + type: 2, + label: `run latest`, + style: 1, + custom_id: "kato-run", + }, + ], + }, + ], + }), + }, +}); + +export const stopRepo: customEmbed< + { + error?: string; + data: string; + }[] +> = createCustomEmbed({ + embeds: (repos) => [ + { + title: repos.map((x) => (x.error ? `${x.error} - ${x.data}` : `Stopped ${x.data}`)).join("\n"), + color: repos.some((x) => x.error) ? 0xff0000 : 0x00ff00, + }, + ], + message: (repos) => ({ + embeds: stopRepo.embeds(repos), + }), +}); + +interface listRepoStats extends Stats { + name: string; +} + +export const listRepo: customEmbed = createCustomEmbed({ + embeds: (repos) => [ + { + title: "These are the current repositories", + fields: repos.map((x) => ({ + name: x.name, + value: `**Created:** \n**Last Modified:** `, + })), + }, + ], +}); + +export const selectRepo: customEmbed = { + ...notImplemented, + error, +}; diff --git a/anify-manager-recode/src/discord/types.d.ts b/anify-manager-recode/src/discord/types.d.ts new file mode 100644 index 0000000..5b91a6a --- /dev/null +++ b/anify-manager-recode/src/discord/types.d.ts @@ -0,0 +1 @@ +declare module 'eris/esm'; \ No newline at end of file diff --git a/anify-manager-recode/src/env.ts b/anify-manager-recode/src/env.ts new file mode 100644 index 0000000..8cdcc24 --- /dev/null +++ b/anify-manager-recode/src/env.ts @@ -0,0 +1,6 @@ +// All environment variables. +export const env = { + DISCORD_TOKEN: process.env.DISCORD_TOKEN, + GUILD_ID: process.env.GUILD_ID, + ADMIN_ROLE_ID: process.env.ADMIN_ROLE_ID, +}; diff --git a/anify-manager-recode/src/index.ts b/anify-manager-recode/src/index.ts new file mode 100644 index 0000000..475e325 --- /dev/null +++ b/anify-manager-recode/src/index.ts @@ -0,0 +1 @@ +import "./discord/client"; diff --git a/anify-manager-recode/src/utils/fs/health.ts b/anify-manager-recode/src/utils/fs/health.ts new file mode 100644 index 0000000..1d58417 --- /dev/null +++ b/anify-manager-recode/src/utils/fs/health.ts @@ -0,0 +1,93 @@ +import fs from "fs"; +import path from "path"; + +import { repositories, buildCommands } from "../../config"; + +interface Health { + file: string; + path: string; + status: "healthy" | "unhealthy" | "unknown"; + errors: { + reason: string; + raw?: any; + }[]; +} + +const viewBuilds = async () => { + const healthCollection = new Map(); + + try { + const files = await fs.promises.readdir("./builds"); + + for (const file of files) { + const subFiles = await fs.promises.readdir(`./builds/${file}`); + const health: Health = { + status: "healthy", + file, + path: `./builds/${file}`, + errors: [], + }; + + if (subFiles.length !== repositories.length + 1) { + health.status = "unhealthy"; + health.errors.push({ + reason: "Missing files", + }); + } + + const data = await fs.promises.readFile(`./builds/${file}/logs/build.log`); + const dataString = data.toString(); + + if (dataString.includes("error")) { + health.status = "unknown"; + health.errors.push({ + reason: "Error in build.log - 'error' found", + raw: `if (dataString.includes("error")) {`, + }); + } else if (!dataString.match(/Build finished at .+/g)) { + health.status = "unhealthy"; + health.errors.push({ + reason: "Error in build.log - no build finished at", + raw: `!dataString.match( /Build finished at .+/g )`, + }); + } + + for (const repo of repositories) { + const repoPath = path.join(`./builds/${file}`, repo.name); + if (!fs.existsSync(repoPath)) { + health.errors.push({ + reason: `Missing repo ${repo.name}`, + }); + continue; + } + + const repositoryFiles = await fs.promises.readdir(repoPath); + if (buildCommands[repo.name][".env"]) { + if (!repositoryFiles.includes(".env")) { + health.errors.push({ + reason: `Missing .env in ${repo.name}`, + raw: `if (buildCommands[repo.name][".env"]) {`, + }); + } + } + if (!repositoryFiles.includes("node_modules")) { + health.errors.push({ + reason: `Missing node_modules in ${repo.name}`, + raw: `if (!repositoryFiles.includes("node_modules")) {`, + }); + } + } + + healthCollection.set(file, health); + } + + return healthCollection; + } catch (err) { + console.error(err); + } +}; + +export default viewBuilds; +export { viewBuilds }; + +export { Health }; diff --git a/anify-manager-recode/src/utils/fs/view.ts b/anify-manager-recode/src/utils/fs/view.ts new file mode 100644 index 0000000..4828368 --- /dev/null +++ b/anify-manager-recode/src/utils/fs/view.ts @@ -0,0 +1,27 @@ +// this is a file to view all the folders from the builds folder + +import fs, { existsSync } from "fs"; +import path from "path"; + +interface ListRepoStats extends fs.Stats { + name: string; +} + +export default function listDirectoryStats(): ListRepoStats[] { + if (!existsSync(path.join(import.meta.dir, "..", "..", "..", "builds"))) { + fs.mkdirSync(path.join(import.meta.dir, "..", "..", "..", "builds"), { recursive: true }); + } + + const files = fs.readdirSync(path.join(import.meta.dir, "..", "..", "..", "builds")); + return files + .map((file) => { + const fileStats = fs.statSync(path.join(import.meta.dir, "..", "..", "..", "builds", file)); + return { ...fileStats, name: file }; + }) + .filter((x) => { + return x.name !== ".gitkeep"; + }) + .sort((a, b) => { + return b.mtimeMs - a.mtimeMs; + }); +} diff --git a/anify-manager-recode/src/utils/pm2/build.ts b/anify-manager-recode/src/utils/pm2/build.ts new file mode 100644 index 0000000..4ff425f --- /dev/null +++ b/anify-manager-recode/src/utils/pm2/build.ts @@ -0,0 +1,95 @@ +import { buildCommands, repositories } from "../../config"; +import { exec } from "child_process"; +import { promisify } from "util"; +import { copyFileSync, createWriteStream, existsSync, mkdirSync } from "fs"; + +const execPromise = promisify(exec); + +export default async function build(label: string, name: string[], count: number) { + let data: { error?: any[]; data: any[] } = { + error: undefined, + data: [], + }; + + const repoNames = name.map((repoName) => repoName.replace(/ /g, "-")); + + const startTime = new Date(); + const startTimeMs = startTime.getTime(); + + function timeFromStart() { + return (new Date().getTime() - startTimeMs) / 1000; + } + + try { + const buildPath = `builds/${label}-${count}`; + const logPath = `${buildPath}/logs`; + + if (existsSync(buildPath)) throw new Error(`Build already exists for ${label}`); + mkdirSync(buildPath); + mkdirSync(logPath); + + const logStream = createWriteStream(`${logPath}/build.log`, {}); + logStream.write(`Build started at ${startTime}\n`); + + const writeToLogStream = (output: any, repoName: string | unknown) => { + const timeNow = timeFromStart().toFixed(2); + const msg = `[${repoName} - ${timeNow}s] `; + + output?.split("\n").forEach((line: string) => { + logStream?.write(msg + line + "\n"); + console.log(msg + line); + }); + }; + + const promises = repoNames.map(async (repoName) => { + const filteredRepos = repositories.filter((repo) => repo.name === repoName); + if (filteredRepos.length !== 1) throw new Error(`Invalid repository name ${repoName}`); + + let output; + const repo = filteredRepos[0]; + + writeToLogStream(`Cloning ${repo.name}`, repo.name); + let localCommand = `cd ${buildPath} && git clone ${repo.url} ${repo.name}`; + + output = await execPromise(localCommand, {}); + + writeToLogStream(output.stdout, repo.name); + writeToLogStream(output.stderr, repo.name); + + localCommand = `cd ${buildPath}/${repo.name} && pnpm install`; + output = await execPromise(localCommand); + + writeToLogStream(output.stdout, repo.name); + writeToLogStream(output.stderr, repo.name); + + const src = buildCommands[repo.name][".env"]; + writeToLogStream(src, repo.name); + if (src) { + const dest = `${buildPath}/${repo.name}/.env`; + copyFileSync(src, dest); + + writeToLogStream(dest, repo.name); + } + + localCommand = `cd ${buildPath}/${repo.name} && ${buildCommands[repo.name].command}`; + output = await execPromise(localCommand); + + writeToLogStream(output.stdout, repo.name); + writeToLogStream(output.stderr, repo.name); + + logStream.write(`Build finished at ${new Date()} and took ${timeFromStart()}s\n`); + + data.data.push({ + [repoName]: "success", + }); + }); + + await Promise.all(promises); + } catch (error) { + const errorMessage = (error as any).message || error; + console.error(`buildRepo error: ${errorMessage}`); + data.error = [{ message: errorMessage }]; + } + + return data; +} diff --git a/anify-manager-recode/src/utils/pm2/index.ts b/anify-manager-recode/src/utils/pm2/index.ts new file mode 100644 index 0000000..181b424 --- /dev/null +++ b/anify-manager-recode/src/utils/pm2/index.ts @@ -0,0 +1,7 @@ +import list from "./list"; +import kill from "./kill"; +import run from "./run"; +import build from "./build"; +import update from "./update"; + +export { list, kill, run, build, update }; diff --git a/anify-manager-recode/src/utils/pm2/initalizePm2.ts b/anify-manager-recode/src/utils/pm2/initalizePm2.ts new file mode 100644 index 0000000..f0bad1d --- /dev/null +++ b/anify-manager-recode/src/utils/pm2/initalizePm2.ts @@ -0,0 +1,17 @@ +import pm2 from "pm2"; + +let pm2Initilized: boolean = false; + +export default (): Promise => { + if (pm2Initilized) return Promise.resolve(); + return new Promise((resolve, reject) => { + pm2.connect((err) => { + if (err) { + console.error(err); + reject(err); + } + pm2Initilized = true; + resolve(); + }); + }); +}; diff --git a/anify-manager-recode/src/utils/pm2/kill.ts b/anify-manager-recode/src/utils/pm2/kill.ts new file mode 100644 index 0000000..bc34883 --- /dev/null +++ b/anify-manager-recode/src/utils/pm2/kill.ts @@ -0,0 +1,32 @@ +import pm2 from "pm2"; +import initalizePm2 from "./initalizePm2"; + +interface IResponse { + error?: string; + data: string; +} + +const kill = async (names: string | number | (string | number)[]): Promise => { + await initalizePm2(); + + if (!Array.isArray(names)) { + names = [names]; + } + + return Promise.all( + names.map((name) => { + return new Promise((resolve, reject) => { + pm2.delete(name, (err, results) => { + if (err) { + resolve({ error: err.message as string, data: name as string }); + } else { + resolve({ data: "success" }); + } + }); + }); + }) + ); +}; + +export default kill; +export { kill }; diff --git a/anify-manager-recode/src/utils/pm2/list.ts b/anify-manager-recode/src/utils/pm2/list.ts new file mode 100644 index 0000000..6e756d6 --- /dev/null +++ b/anify-manager-recode/src/utils/pm2/list.ts @@ -0,0 +1,27 @@ +import pm2 from "pm2"; +import initalizePm2 from "./initalizePm2"; + +export interface IResponse extends Object { + error?: string; + data: { + name?: string; + pid?: number; + }[]; +} + +const list = async (): Promise => { + await initalizePm2(); + return new Promise((resolve, reject) => { + pm2.list((err, list) => { + if (err) { + console.error(err); + return resolve({ error: err.message, data: [] }); + } + + resolve({ data: list.map((x) => ({ name: x.name, pid: x.pid })) }); + }); + }); +}; + +export default list; +export { list }; diff --git a/anify-manager-recode/src/utils/pm2/run.ts b/anify-manager-recode/src/utils/pm2/run.ts new file mode 100644 index 0000000..faef9fe --- /dev/null +++ b/anify-manager-recode/src/utils/pm2/run.ts @@ -0,0 +1,50 @@ +import { runCommands } from "../../config"; +import initalizePm2 from "./initalizePm2"; +import { promisify } from "util"; +import pm2 from "pm2"; +import fs from "fs"; + +interface BuildDetail { + error?: string; + data?: string; +} + +const run = async (folderName: string): Promise => { + await initalizePm2(); + + const builds = (await promisify(fs.readdir)("./builds")) as any[]; + const buildStats = await Promise.all(builds.map((build) => promisify(fs.stat)(`./builds/${build}`))); + const latestBuild = folderName ?? builds[buildStats.filter((stat: any) => stat.isDirectory()).length - 1]; + + const keys = Object.keys(runCommands); + const buildDetails: BuildDetail[] = []; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const value = runCommands[key]; + + await new Promise((resolve, reject) => { + pm2.start( + { + script: `pnpm`, + args: value.split(" "), + cwd: `./builds/${latestBuild}/${key}`, + name: latestBuild + "-" + key, + }, + (err, apps) => { + if (err) { + console.log(err); + buildDetails.push({ error: err.message }); + } else { + buildDetails.push({ data: `running ${latestBuild}, ${key}` }); + } + + resolve(); + } + ); + }); + } + + return buildDetails; +}; + +export default run; diff --git a/anify-manager-recode/src/utils/pm2/update.ts b/anify-manager-recode/src/utils/pm2/update.ts new file mode 100644 index 0000000..b20082d --- /dev/null +++ b/anify-manager-recode/src/utils/pm2/update.ts @@ -0,0 +1,143 @@ +import { buildCommands, repositories } from "../../config"; +import fs from "fs"; +import { exec, ChildProcess } from "child_process"; +import { promisify } from "util"; +import { WriteStream, copyFileSync, createWriteStream, existsSync, mkdirSync, readFileSync } from "fs"; + +const execPromise = promisify(exec); + +const customPromisify = ( + localCommand: string +): { + promise: Promise; + child: ChildProcess; +} => { + const child = exec(localCommand); + const promise = new Promise((resolve, reject) => { + child.on("error", reject); + child.on("exit", resolve); + child.on("close", resolve); + }); + + return { + promise, + child, + }; +}; + +export default async function update({ label = "auto", name = Object.keys(buildCommands) }: { label?: string; name?: string[] }) { + let data: { error?: any[]; data: any[] } = { + error: undefined, + data: [], + }; + + const repoNames = name?.map((repoName) => repoName.replace(/ /g, "-")); + + const startTime = new Date(); + const startTimeMs = startTime.getTime(); + + function timeFromStart() { + return (new Date().getTime() - startTimeMs) / 1000; + } + + try { + const buildPath = `builds/${label}`; + const logPathPartial = `${buildPath}/logs`; + const logPath = `${logPathPartial}/update-${new Date().toDateString().split(" ").join("-")}.log`; + let firstBuild = false; + + if (!existsSync(buildPath)) { + firstBuild = true; + mkdirSync(buildPath); + mkdirSync(logPathPartial); + } + + // get the latest commit hash + const logStream = createWriteStream(`${logPath}`, {}); + logStream.write(`Update started at ${startTime}\n`); + + const writeToLogStream = (output: any, repoName: string | unknown) => { + const timeNow = timeFromStart().toFixed(2); + const msg = `[${repoName} - ${timeNow}s] `; + + output?.split("\n").forEach((line: string) => { + logStream?.write(msg + line + "\n"); + console.log(msg + line); + }); + }; + + const promises = repoNames?.map(async (repoName) => { + const filteredRepos = repositories.filter((repo) => repo.name === repoName); + if (filteredRepos.length !== 1) throw new Error(`Invalid repository name ${repoName}`); + + let output; + const repo = filteredRepos[0]; + + writeToLogStream(`Updating ${repo.name}`, repo.name); + let localCommand: any; + + if (firstBuild) { + localCommand = `cd ${buildPath} && git clone ${repo.url} ${repo.name}`; + output = await execPromise(localCommand); + + writeToLogStream(output.stdout, repo.name); + writeToLogStream(output.stderr, repo.name); + } + + localCommand = `cd ${buildPath}/${repo.name} && git pull`; + output = customPromisify(localCommand); + + output.child.stdout?.on("data", (d) => writeToLogStream(d, repo.name)); + output.child.stderr?.on("data", (d) => writeToLogStream(d, repo.name)); + + await output.promise; + + localCommand = `cd ${buildPath}/${repo.name} && pnpm install`; + output = customPromisify(localCommand); + + output.child.stdout?.on("data", (d) => writeToLogStream(d, repo.name)); + output.child.stderr?.on("data", (d) => writeToLogStream(d, repo.name)); + + await output.promise; + + const src = buildCommands[repo.name][".env"]; + writeToLogStream(src, repo.name); + if (src) { + const dest = `${buildPath}/${repo.name}/.env`; + copyFileSync(src, dest); + + writeToLogStream(dest, repo.name); + } + + localCommand = `cd ${buildPath}/${repo.name} && ${buildCommands[repo.name].command}`; + output = customPromisify(localCommand); + + output.child.stdout?.on("data", (d) => writeToLogStream(d, repo.name)); + output.child.stderr?.on("data", (d) => writeToLogStream(d, repo.name)); + + await output.promise; + + logStream.write(`Build finished at ${new Date()} and took ${timeFromStart()}s\n`); + + data.data.push({ + [repoName]: "success", + }); + }); + + data.data.push({ + logsPath: logPath, + }); + + await Promise.all(promises); + + // we assume a victroy so now run fs.utimesSync( path, atime, mtime ) on the buildFolder + const newTime = new Date(); + fs.utimesSync(buildPath, newTime, newTime); + } catch (error) { + // @ts-ignore + const errorMessage = error.message || error; + console.error(`buildRepo error: ${errorMessage}`); + data.error = [{ message: errorMessage }]; + } + return data; +} diff --git a/anify-manager-recode/tsconfig.json b/anify-manager-recode/tsconfig.json new file mode 100644 index 0000000..388a057 --- /dev/null +++ b/anify-manager-recode/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "jsx": "preserve", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [ + "bun-types" // add Bun global + ] + } +} From 1d8d2114a786d95af9b8afc4e292471950d238c1 Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 13 Sep 2023 08:29:26 -0400 Subject: [PATCH 32/77] Merge manager recode to manager --- .gitignore | 3 +- anify-backend/src/index.ts | 6 +- anify-cli/.eslintignore | 1 - anify-cli/.eslintrc | 33 - anify-cli/.prettierignore | 11 - anify-cli/.prettierrc.json | 13 - anify-cli/READMD.md | 2 - anify-cli/dist/index.d.ts | 1 - anify-cli/dist/index.js | 97 - anify-cli/dist/lib/build.d.ts | 2 - anify-cli/dist/lib/build.js | 59 - anify-cli/dist/lib/loadEnv.d.ts | 3 - anify-cli/dist/lib/loadEnv.js | 76 - anify-cli/dist/prompts/auth.d.ts | 1 - anify-cli/dist/prompts/auth.js | 22 - anify-cli/dist/prompts/backend.d.ts | 1 - anify-cli/dist/prompts/backend.js | 21 - anify-cli/dist/prompts/env.d.ts | 4 - anify-cli/dist/prompts/env.js | 100 - anify-cli/dist/prompts/frontend.d.ts | 1 - anify-cli/dist/prompts/frontend.js | 21 - anify-cli/dist/prompts/manager.d.ts | 1 - anify-cli/dist/prompts/manager.js | 21 - anify-cli/dist/types/index.d.ts | 6 - anify-cli/dist/types/index.js | 2 - anify-cli/package-lock.json | 4600 ------------- anify-cli/package.json | 47 - anify-cli/src/index.ts | 71 - anify-cli/src/lib/build.ts | 65 - anify-cli/src/lib/loadEnv.ts | 85 - anify-cli/src/prompts/auth.ts | 21 - anify-cli/src/prompts/backend.ts | 19 - anify-cli/src/prompts/env.ts | 84 - anify-cli/src/prompts/frontend.ts | 19 - anify-cli/src/prompts/manager.ts | 19 - anify-cli/src/types/index.ts | 6 - anify-cli/tsconfig.json | 33 - anify-cli/yarn.lock | 2345 ------- anify-manager-recode/.eslintignore | 2 - anify-manager-recode/.eslintrc | 33 - anify-manager-recode/.prettierignore | 12 - anify-manager-recode/.prettierrc.json | 13 - anify-manager-recode/package.json | 27 - anify-manager-recode/src/index.ts | 1 - .../src/utils/pm2/initalizePm2.ts | 17 - anify-manager-recode/src/utils/pm2/list.ts | 27 - anify-manager-recode/tsconfig.json | 22 - anify-manager/.env.example | 14 - anify-manager/.eslintignore | 1 + .../.gitignore | 0 anify-manager/.prettierignore | 3 +- anify-manager/READMD.md | 2 - .../README.md | 0 anify-manager/dist/bot/channels.json | 7 - anify-manager/dist/bot/colors.json | 6 - anify-manager/dist/bot/commands/assign.d.ts | 6 - anify-manager/dist/bot/commands/assign.js | 60 - anify-manager/dist/bot/commands/get.d.ts | 6 - anify-manager/dist/bot/commands/get.js | 41 - anify-manager/dist/bot/commands/keys.d.ts | 6 - anify-manager/dist/bot/commands/keys.js | 77 - anify-manager/dist/bot/commands/ping.d.ts | 6 - anify-manager/dist/bot/commands/ping.js | 9 - anify-manager/dist/bot/commands/site.d.ts | 6 - anify-manager/dist/bot/commands/site.js | 19 - anify-manager/dist/bot/commands/stats.d.ts | 6 - anify-manager/dist/bot/commands/stats.js | 102 - anify-manager/dist/bot/commands/unassign.d.ts | 6 - anify-manager/dist/bot/commands/unassign.js | 47 - .../dist/bot/commands/updateKeys.d.ts | 6 - anify-manager/dist/bot/commands/updateKeys.js | 45 - anify-manager/dist/bot/events/buttons.d.ts | 2 - anify-manager/dist/bot/events/buttons.js | 159 - .../dist/bot/events/guildMemberAdd.d.ts | 2 - .../dist/bot/events/guildMemberAdd.js | 16 - .../dist/bot/events/guildMemberRemove.d.ts | 2 - .../dist/bot/events/guildMemberRemove.js | 7 - .../dist/bot/events/interactionCreate.d.ts | 2 - .../dist/bot/events/interactionCreate.js | 24 - .../dist/bot/events/messageCreate.d.ts | 2 - .../dist/bot/events/messageCreate.js | 51 - anify-manager/dist/bot/events/ready.d.ts | 2 - anify-manager/dist/bot/events/ready.js | 11 - anify-manager/dist/bot/events/status.d.ts | 2 - anify-manager/dist/bot/events/status.js | 78 - anify-manager/dist/bot/index.d.ts | 10 - anify-manager/dist/bot/index.js | 127 - anify-manager/dist/bot/roles.json | 8 - anify-manager/dist/index.d.ts | 1 - anify-manager/dist/index.js | 70 - anify-manager/dist/manager/index.d.ts | 12 - anify-manager/dist/manager/index.js | 135 - anify-manager/dist/scripts/startBot.d.ts | 1 - anify-manager/dist/scripts/startBot.js | 14 - anify-manager/dist/test.d.ts | 1 - anify-manager/dist/test.js | 4 - anify-manager/package-lock.json | 6029 ----------------- anify-manager/package.json | 73 +- anify-manager/src/bot/channels.json | 7 - anify-manager/src/bot/colors.json | 6 - anify-manager/src/bot/commands/assign.ts | 62 - anify-manager/src/bot/commands/get.ts | 40 - anify-manager/src/bot/commands/keys.ts | 81 - anify-manager/src/bot/commands/ping.ts | 8 - anify-manager/src/bot/commands/site.ts | 16 - anify-manager/src/bot/commands/stats.ts | 119 - anify-manager/src/bot/commands/unassign.ts | 47 - anify-manager/src/bot/commands/updateKeys.ts | 42 - anify-manager/src/bot/events/buttons.ts | 163 - .../src/bot/events/guildMemberAdd.ts | 13 - .../src/bot/events/guildMemberRemove.ts | 7 - .../src/bot/events/interactionCreate.ts | 21 - anify-manager/src/bot/events/messageCreate.ts | 53 - anify-manager/src/bot/events/ready.ts | 7 - anify-manager/src/bot/events/status.ts | 87 - anify-manager/src/bot/index.ts | 104 - anify-manager/src/bot/roles.json | 8 - .../src/config.ts | 4 +- .../src/discord/client.ts | 0 .../src/discord/commands/anify/list.ts | 0 .../src/discord/commands/anify/pull.ts | 5 +- .../src/discord/commands/anify/run.ts | 73 + .../src/discord/commands/anify/running.ts | 40 + .../src/discord/responses.ts | 0 .../src/discord/responses/anify.ts | 2 +- .../src/discord/types.d.ts | 0 .../src/env.ts | 0 anify-manager/src/index.ts | 71 +- anify-manager/src/manager/index.ts | 139 - anify-manager/src/scripts/startBot.ts | 11 - .../src/utils/fs/health.ts | 0 .../src/utils/fs/view.ts | 0 .../src/utils/pm2/build.ts | 5 +- .../src/utils/pm2/index.ts | 2 + .../src/utils/pm2/kill.ts | 14 +- anify-manager/src/utils/pm2/list.ts | 25 + .../src/utils/pm2/run.ts | 47 +- .../src/utils/pm2/update.ts | 2 +- anify-manager/tsconfig.json | 41 +- anify-manager/yarn.lock | 3362 --------- anify-startup/.gitignore | 172 + anify-startup/README.md | 15 + anify-startup/index.ts | 77 + anify-startup/package.json | 19 + anify-startup/tsconfig.json | 22 + package.json | 1 - 146 files changed, 531 insertions(+), 19911 deletions(-) delete mode 100644 anify-cli/.eslintignore delete mode 100644 anify-cli/.eslintrc delete mode 100644 anify-cli/.prettierignore delete mode 100644 anify-cli/.prettierrc.json delete mode 100644 anify-cli/READMD.md delete mode 100644 anify-cli/dist/index.d.ts delete mode 100644 anify-cli/dist/index.js delete mode 100644 anify-cli/dist/lib/build.d.ts delete mode 100644 anify-cli/dist/lib/build.js delete mode 100644 anify-cli/dist/lib/loadEnv.d.ts delete mode 100644 anify-cli/dist/lib/loadEnv.js delete mode 100644 anify-cli/dist/prompts/auth.d.ts delete mode 100644 anify-cli/dist/prompts/auth.js delete mode 100644 anify-cli/dist/prompts/backend.d.ts delete mode 100644 anify-cli/dist/prompts/backend.js delete mode 100644 anify-cli/dist/prompts/env.d.ts delete mode 100644 anify-cli/dist/prompts/env.js delete mode 100644 anify-cli/dist/prompts/frontend.d.ts delete mode 100644 anify-cli/dist/prompts/frontend.js delete mode 100644 anify-cli/dist/prompts/manager.d.ts delete mode 100644 anify-cli/dist/prompts/manager.js delete mode 100644 anify-cli/dist/types/index.d.ts delete mode 100644 anify-cli/dist/types/index.js delete mode 100644 anify-cli/package-lock.json delete mode 100644 anify-cli/package.json delete mode 100644 anify-cli/src/index.ts delete mode 100644 anify-cli/src/lib/build.ts delete mode 100644 anify-cli/src/lib/loadEnv.ts delete mode 100644 anify-cli/src/prompts/auth.ts delete mode 100644 anify-cli/src/prompts/backend.ts delete mode 100644 anify-cli/src/prompts/env.ts delete mode 100644 anify-cli/src/prompts/frontend.ts delete mode 100644 anify-cli/src/prompts/manager.ts delete mode 100644 anify-cli/src/types/index.ts delete mode 100644 anify-cli/tsconfig.json delete mode 100644 anify-cli/yarn.lock delete mode 100644 anify-manager-recode/.eslintignore delete mode 100644 anify-manager-recode/.eslintrc delete mode 100644 anify-manager-recode/.prettierignore delete mode 100644 anify-manager-recode/.prettierrc.json delete mode 100644 anify-manager-recode/package.json delete mode 100644 anify-manager-recode/src/index.ts delete mode 100644 anify-manager-recode/src/utils/pm2/initalizePm2.ts delete mode 100644 anify-manager-recode/src/utils/pm2/list.ts delete mode 100644 anify-manager-recode/tsconfig.json delete mode 100644 anify-manager/.env.example rename {anify-manager-recode => anify-manager}/.gitignore (100%) delete mode 100644 anify-manager/READMD.md rename {anify-manager-recode => anify-manager}/README.md (100%) delete mode 100644 anify-manager/dist/bot/channels.json delete mode 100644 anify-manager/dist/bot/colors.json delete mode 100644 anify-manager/dist/bot/commands/assign.d.ts delete mode 100644 anify-manager/dist/bot/commands/assign.js delete mode 100644 anify-manager/dist/bot/commands/get.d.ts delete mode 100644 anify-manager/dist/bot/commands/get.js delete mode 100644 anify-manager/dist/bot/commands/keys.d.ts delete mode 100644 anify-manager/dist/bot/commands/keys.js delete mode 100644 anify-manager/dist/bot/commands/ping.d.ts delete mode 100644 anify-manager/dist/bot/commands/ping.js delete mode 100644 anify-manager/dist/bot/commands/site.d.ts delete mode 100644 anify-manager/dist/bot/commands/site.js delete mode 100644 anify-manager/dist/bot/commands/stats.d.ts delete mode 100644 anify-manager/dist/bot/commands/stats.js delete mode 100644 anify-manager/dist/bot/commands/unassign.d.ts delete mode 100644 anify-manager/dist/bot/commands/unassign.js delete mode 100644 anify-manager/dist/bot/commands/updateKeys.d.ts delete mode 100644 anify-manager/dist/bot/commands/updateKeys.js delete mode 100644 anify-manager/dist/bot/events/buttons.d.ts delete mode 100644 anify-manager/dist/bot/events/buttons.js delete mode 100644 anify-manager/dist/bot/events/guildMemberAdd.d.ts delete mode 100644 anify-manager/dist/bot/events/guildMemberAdd.js delete mode 100644 anify-manager/dist/bot/events/guildMemberRemove.d.ts delete mode 100644 anify-manager/dist/bot/events/guildMemberRemove.js delete mode 100644 anify-manager/dist/bot/events/interactionCreate.d.ts delete mode 100644 anify-manager/dist/bot/events/interactionCreate.js delete mode 100644 anify-manager/dist/bot/events/messageCreate.d.ts delete mode 100644 anify-manager/dist/bot/events/messageCreate.js delete mode 100644 anify-manager/dist/bot/events/ready.d.ts delete mode 100644 anify-manager/dist/bot/events/ready.js delete mode 100644 anify-manager/dist/bot/events/status.d.ts delete mode 100644 anify-manager/dist/bot/events/status.js delete mode 100644 anify-manager/dist/bot/index.d.ts delete mode 100644 anify-manager/dist/bot/index.js delete mode 100644 anify-manager/dist/bot/roles.json delete mode 100644 anify-manager/dist/index.d.ts delete mode 100644 anify-manager/dist/index.js delete mode 100644 anify-manager/dist/manager/index.d.ts delete mode 100644 anify-manager/dist/manager/index.js delete mode 100644 anify-manager/dist/scripts/startBot.d.ts delete mode 100644 anify-manager/dist/scripts/startBot.js delete mode 100644 anify-manager/dist/test.d.ts delete mode 100644 anify-manager/dist/test.js delete mode 100644 anify-manager/package-lock.json delete mode 100644 anify-manager/src/bot/channels.json delete mode 100644 anify-manager/src/bot/colors.json delete mode 100644 anify-manager/src/bot/commands/assign.ts delete mode 100644 anify-manager/src/bot/commands/get.ts delete mode 100644 anify-manager/src/bot/commands/keys.ts delete mode 100644 anify-manager/src/bot/commands/ping.ts delete mode 100644 anify-manager/src/bot/commands/site.ts delete mode 100644 anify-manager/src/bot/commands/stats.ts delete mode 100644 anify-manager/src/bot/commands/unassign.ts delete mode 100644 anify-manager/src/bot/commands/updateKeys.ts delete mode 100644 anify-manager/src/bot/events/buttons.ts delete mode 100644 anify-manager/src/bot/events/guildMemberAdd.ts delete mode 100644 anify-manager/src/bot/events/guildMemberRemove.ts delete mode 100644 anify-manager/src/bot/events/interactionCreate.ts delete mode 100644 anify-manager/src/bot/events/messageCreate.ts delete mode 100644 anify-manager/src/bot/events/ready.ts delete mode 100644 anify-manager/src/bot/events/status.ts delete mode 100644 anify-manager/src/bot/index.ts delete mode 100644 anify-manager/src/bot/roles.json rename {anify-manager-recode => anify-manager}/src/config.ts (79%) rename {anify-manager-recode => anify-manager}/src/discord/client.ts (100%) rename {anify-manager-recode => anify-manager}/src/discord/commands/anify/list.ts (100%) rename {anify-manager-recode => anify-manager}/src/discord/commands/anify/pull.ts (82%) create mode 100644 anify-manager/src/discord/commands/anify/run.ts create mode 100644 anify-manager/src/discord/commands/anify/running.ts rename {anify-manager-recode => anify-manager}/src/discord/responses.ts (100%) rename {anify-manager-recode => anify-manager}/src/discord/responses/anify.ts (96%) rename {anify-manager-recode => anify-manager}/src/discord/types.d.ts (100%) rename {anify-manager-recode => anify-manager}/src/env.ts (100%) delete mode 100644 anify-manager/src/manager/index.ts delete mode 100644 anify-manager/src/scripts/startBot.ts rename {anify-manager-recode => anify-manager}/src/utils/fs/health.ts (100%) rename {anify-manager-recode => anify-manager}/src/utils/fs/view.ts (100%) rename {anify-manager-recode => anify-manager}/src/utils/pm2/build.ts (96%) rename {anify-manager-recode => anify-manager}/src/utils/pm2/index.ts (65%) rename {anify-manager-recode => anify-manager}/src/utils/pm2/kill.ts (51%) create mode 100644 anify-manager/src/utils/pm2/list.ts rename {anify-manager-recode => anify-manager}/src/utils/pm2/run.ts (52%) rename {anify-manager-recode => anify-manager}/src/utils/pm2/update.ts (97%) delete mode 100644 anify-manager/yarn.lock create mode 100644 anify-startup/.gitignore create mode 100644 anify-startup/README.md create mode 100644 anify-startup/index.ts create mode 100644 anify-startup/package.json create mode 100644 anify-startup/tsconfig.json diff --git a/.gitignore b/.gitignore index e537ed4..16fe882 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,5 @@ database.json /manga bun.lockb goodProxies.json -proxies.json \ No newline at end of file +proxies.json +/builds \ No newline at end of file diff --git a/anify-backend/src/index.ts b/anify-backend/src/index.ts index 3d5216f..978f05d 100644 --- a/anify-backend/src/index.ts +++ b/anify-backend/src/index.ts @@ -14,7 +14,7 @@ import { loadMapping } from "./lib/impl/mappings"; import { fetchChapters } from "./content/impl/chapters"; before().then(async (_) => { - //await start(); + await start(); const chapter = { id: "/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1", title: "Chapter 1", @@ -22,9 +22,9 @@ before().then(async (_) => { updatedAt: 1660688888000, }; - const pages = await mangaProviders.mangasee.fetchPages("/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1"); + //const pages = await mangaProviders.mangasee.fetchPages("/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1"); - await loadPDF({ id: "dc481ed5-4925-4f3c-bac1-e73f1e7ed338", providerId: "mangasee", chapter, pages: pages ?? [] }).then(console.log); + //await loadPDF({ id: "dc481ed5-4925-4f3c-bac1-e73f1e7ed338", providerId: "mangasee", chapter, pages: pages ?? [] }).then(console.log); }); async function before() { diff --git a/anify-cli/.eslintignore b/anify-cli/.eslintignore deleted file mode 100644 index cf44e14..0000000 --- a/anify-cli/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -**/*.js \ No newline at end of file diff --git a/anify-cli/.eslintrc b/anify-cli/.eslintrc deleted file mode 100644 index 13b5ac5..0000000 --- a/anify-cli/.eslintrc +++ /dev/null @@ -1,33 +0,0 @@ -{ - "parser": "@typescript-eslint/parser", - "plugins": [ - "@typescript-eslint" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "rules": { - "@typescript-eslint/ban-types": "warn", - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-empty-function": "off", - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-namespace": "off", - "@typescript-eslint/no-loss-of-precision": "off", - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-non-null-asserted-optional-chain": "off", - "@typescript-eslint/no-unnecessary-type-constraint": "warn", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/no-var-requires": "warn", - "no-console": "off", - "no-empty": "warn", - "no-prototype-builtins": "off", - "no-redeclare": "warn", - "no-useless-escape": "off", - "no-async-promise-executor": "off", - "prefer-const": "warn", - "array-bracket-spacing": ["error", "never"] - } -} \ No newline at end of file diff --git a/anify-cli/.prettierignore b/anify-cli/.prettierignore deleted file mode 100644 index dffb4ad..0000000 --- a/anify-cli/.prettierignore +++ /dev/null @@ -1,11 +0,0 @@ -node_modules -*.js -*.d.ts -*.md -*.json -*.lock -*.yml -*.yaml -Dockerfile -Dockerfile.* -.eslintrc \ No newline at end of file diff --git a/anify-cli/.prettierrc.json b/anify-cli/.prettierrc.json deleted file mode 100644 index 0e41e21..0000000 --- a/anify-cli/.prettierrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "useTabs": false, - "tabWidth": 4, - "semi": true, - "singleQuote": false, - "bracketSpacing": true, - "bracketSameLine": false, - "arrowParens": "always", - "parser": "typescript", - "printWidth": 10000, - "proseWrap": "never", - "endOfLine": "lf" -} diff --git a/anify-cli/READMD.md b/anify-cli/READMD.md deleted file mode 100644 index 67cdf63..0000000 --- a/anify-cli/READMD.md +++ /dev/null @@ -1,2 +0,0 @@ -# anify-manager -This documentation will be updated soon. \ No newline at end of file diff --git a/anify-cli/dist/index.d.ts b/anify-cli/dist/index.d.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/anify-cli/dist/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/anify-cli/dist/index.js b/anify-cli/dist/index.js deleted file mode 100644 index 5c6940a..0000000 --- a/anify-cli/dist/index.js +++ /dev/null @@ -1,97 +0,0 @@ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const dotenv_1 = __importDefault(require("dotenv")); -dotenv_1.default.config(); -const commander_1 = require("commander"); -const inquirer = __importStar(require("inquirer")); -const env_1 = require("./prompts/env"); -const backend_1 = require("./prompts/backend"); -const frontend_1 = require("./prompts/frontend"); -const auth_1 = require("./prompts/auth"); -const manager_1 = require("./prompts/manager"); -commander_1.program.description("A robust CLI for creating a web server for anime, manga, and light novels.") - .option("-e, -enviornment", "Setup the environment variables.") - .option("-b, -backend", "Setup the backend.") - .option("-f, -frontend", "Setup the frontend.") - .option("-a, -auth", "Setup the authentication.") - .option("-m, -manager", "Setup the manager."); -commander_1.program.parse(); -const options = commander_1.program.opts(); -if (options.e) { - (0, env_1.promptEnvVariables)(); -} -else if (options.b) { - (0, backend_1.promptBackend)(); -} -else if (options.f) { - (0, frontend_1.promptFrontend)(); -} -else if (options.a) { - (0, auth_1.promptAuth)(); -} -else if (options.m) { - (0, manager_1.promptManager)(); -} -else { - promptSetup(); -} -async function promptSetup() { - const { type } = await inquirer.prompt({ - type: "list", - name: "type", - message: "What setup are you looking for?", - choices: [ - "Environmental Variables", - "Backend", - "Frontend", - "Authentication", - "Manager" - ], - default: "Anime", - }); - switch (type) { - case "Environmental Variables": - await (0, env_1.promptEnvVariables)(); - break; - case "Backend": - await (0, backend_1.promptBackend)(); - break; - case "Frontend": - await (0, frontend_1.promptFrontend)(); - break; - case "Authentication": - await (0, auth_1.promptAuth)(); - break; - case "Manager": - await (0, manager_1.promptManager)(); - break; - default: - break; - } -} diff --git a/anify-cli/dist/lib/build.d.ts b/anify-cli/dist/lib/build.d.ts deleted file mode 100644 index c494fb8..0000000 --- a/anify-cli/dist/lib/build.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { Process } from "../types"; -export declare const build: (process: Process) => Promise; diff --git a/anify-cli/dist/lib/build.js b/anify-cli/dist/lib/build.js deleted file mode 100644 index 81993eb..0000000 --- a/anify-cli/dist/lib/build.js +++ /dev/null @@ -1,59 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.build = void 0; -const child_process_1 = __importDefault(require("child_process")); -const colors_1 = __importDefault(require("colors")); -const simulateLoadingDots = () => { - const dots = ['.', '..', '...']; - let i = 0; - const interval = setInterval(() => { - process.stdout.clearLine(0); - process.stdout.cursorTo(0); - process.stdout.write("\x1B[?25l"); // Hide cursor - process.stdout.write(colors_1.default.cyan(`Building${dots[i]}\r`)); - if (i === dots.length - 1) { - i = 0; - } - else { - i++; - } - }, 500); - return interval; -}; -const build = async (process) => { - const child = child_process_1.default.spawn("npm", ["run", "build"], { - cwd: `../${process}`, - stdio: "pipe" - }); - const loadingInterval = simulateLoadingDots(); - return new Promise((resolve, reject) => { - let buildOutput = ""; // Variable to capture build output - child.stdout?.on("data", (data) => { - buildOutput += data.toString(); - }); - child.stderr?.on("data", (data) => { - buildOutput += data.toString(); - }); - child.on("error", (error) => { - clearInterval(loadingInterval); - console.error(colors_1.default.red(`Error starting build process: ${error.message}\n`)); - resolve(false); - }); - child.on("exit", (code) => { - clearInterval(loadingInterval); - if (code === 0) { - console.log(colors_1.default.green("Build completed successfully\n")); - resolve(true); - } - else { - console.error(buildOutput); // Log the error output - console.log(colors_1.default.red("Build failed. Please check the above for errors.\n")); - resolve(false); - } - }); - }); -}; -exports.build = build; diff --git a/anify-cli/dist/lib/loadEnv.d.ts b/anify-cli/dist/lib/loadEnv.d.ts deleted file mode 100644 index df7eb6f..0000000 --- a/anify-cli/dist/lib/loadEnv.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Process } from "../types"; -export declare const loadRequiredEnv: (process: Process) => Promise; -export declare const loadEnv: (process: Process) => Promise>; diff --git a/anify-cli/dist/lib/loadEnv.js b/anify-cli/dist/lib/loadEnv.js deleted file mode 100644 index 7341aa0..0000000 --- a/anify-cli/dist/lib/loadEnv.js +++ /dev/null @@ -1,76 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.loadEnv = exports.loadRequiredEnv = void 0; -const promises_1 = require("fs/promises"); -const fs_1 = require("fs"); -const loadRequiredEnv = async (process) => { - if (!(0, fs_1.existsSync)(`../${process}/.env.example`)) { - return []; - } - const env = await (0, promises_1.readFile)(`../${process}/.env.example`, "utf-8"); - // Convert to JSON - const envVariables = {}; - env.split("\n").forEach((line) => { - if (line.startsWith("#")) { - // Ignore comments - return; - } - const [key, value] = line.split("="); - if (!key || !value) { - return; - } - // Try to parse values into appropriate types - let parsedValue = value.trim(); - parsedValue = parsedValue.startsWith('"') && parsedValue.endsWith('"') ? parsedValue.slice(1, -1) : parsedValue; - if (parsedValue?.toLowerCase() === "true") { - parsedValue = true; - } - else if (parsedValue?.toLowerCase() === "false") { - parsedValue = false; - } - else if (!isNaN(Number(parsedValue))) { - parsedValue = Number(parsedValue); - } - envVariables[key] = parsedValue; - }); - // Return the keys - return Object.keys(envVariables); -}; -exports.loadRequiredEnv = loadRequiredEnv; -const loadEnv = async (process) => { - if (!(0, fs_1.existsSync)(`../${process}/.env`)) { - return {}; - } - const env = await (0, promises_1.readFile)(`../${process}/.env`, "utf-8"); - // Convert to JSON - const envVariables = {}; - env.split("\n").forEach((line) => { - if (line.startsWith("#")) { - // Ignore comments - return; - } - const equalIndex = line.indexOf("="); - if (equalIndex === -1) { - // Skip lines without '=' - return; - } - const key = line.slice(0, equalIndex).trim(); - const value = line.slice(equalIndex + 1).trim(); - // Try to parse values into appropriate types - let parsedValue = value.trim(); - parsedValue = parsedValue.startsWith('"') ? parsedValue.slice(1) : parsedValue; - parsedValue = parsedValue.endsWith('"') ? parsedValue.slice(0, -1) : parsedValue; - if (parsedValue?.toLowerCase() === "true") { - parsedValue = true; - } - else if (parsedValue?.toLowerCase() === "false") { - parsedValue = false; - } - else if (!isNaN(Number(parsedValue))) { - parsedValue = Number(parsedValue); - } - envVariables[key] = parsedValue; - }); - return envVariables; -}; -exports.loadEnv = loadEnv; diff --git a/anify-cli/dist/prompts/auth.d.ts b/anify-cli/dist/prompts/auth.d.ts deleted file mode 100644 index 88a4f70..0000000 --- a/anify-cli/dist/prompts/auth.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function promptAuth(): Promise; diff --git a/anify-cli/dist/prompts/auth.js b/anify-cli/dist/prompts/auth.js deleted file mode 100644 index 0e34bf4..0000000 --- a/anify-cli/dist/prompts/auth.js +++ /dev/null @@ -1,22 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.promptAuth = void 0; -const colors_1 = __importDefault(require("colors")); -const env_1 = require("./env"); -const build_1 = require("../lib/build"); -async function promptAuth() { - console.log(colors_1.default.yellow("Parsing environment variables...")); - const auth = await (0, env_1.parseEnv)("anify-auth" /* Process.AUTH */); - await (0, env_1.promptEnv)("anify-auth" /* Process.AUTH */, auth); - // Test out installing and building - const buildData = await (0, build_1.build)("anify-auth" /* Process.AUTH */); - if (!buildData) { - console.log(colors_1.default.red("Build failed. Please check the above for errors.\n")); - return; - } - console.log(colors_1.default.green("Build succeeded. Authentication server is all setup.")); -} -exports.promptAuth = promptAuth; diff --git a/anify-cli/dist/prompts/backend.d.ts b/anify-cli/dist/prompts/backend.d.ts deleted file mode 100644 index 14f4b0c..0000000 --- a/anify-cli/dist/prompts/backend.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function promptBackend(): Promise; diff --git a/anify-cli/dist/prompts/backend.js b/anify-cli/dist/prompts/backend.js deleted file mode 100644 index 1e828f9..0000000 --- a/anify-cli/dist/prompts/backend.js +++ /dev/null @@ -1,21 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.promptBackend = void 0; -const colors_1 = __importDefault(require("colors")); -const env_1 = require("./env"); -const build_1 = require("../lib/build"); -async function promptBackend() { - console.log(colors_1.default.yellow("Parsing environment variables...")); - const backend = await (0, env_1.parseEnv)("anify-backend" /* Process.BACKEND */); - await (0, env_1.promptEnv)("anify-backend" /* Process.BACKEND */, backend); - // Test out installing and building - const buildData = await (0, build_1.build)("anify-backend" /* Process.BACKEND */); - if (!buildData) { - return; - } - console.log(colors_1.default.green("Build succeeded. Backend server is all setup.")); -} -exports.promptBackend = promptBackend; diff --git a/anify-cli/dist/prompts/env.d.ts b/anify-cli/dist/prompts/env.d.ts deleted file mode 100644 index bbc8d75..0000000 --- a/anify-cli/dist/prompts/env.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Process } from "../types"; -export declare function promptEnvVariables(): Promise; -export declare function parseEnv(process: Process): Promise; -export declare function promptEnv(process: Process, missing: string[]): Promise; diff --git a/anify-cli/dist/prompts/env.js b/anify-cli/dist/prompts/env.js deleted file mode 100644 index 2f07078..0000000 --- a/anify-cli/dist/prompts/env.js +++ /dev/null @@ -1,100 +0,0 @@ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.promptEnv = exports.parseEnv = exports.promptEnvVariables = void 0; -const inquirer = __importStar(require("inquirer")); -const colors_1 = __importDefault(require("colors")); -const loadEnv_1 = require("../lib/loadEnv"); -const promises_1 = require("fs/promises"); -async function promptEnvVariables() { - // Setup environment variables - console.log(colors_1.default.yellow("Parsing environment variables...")); - const backend = await parseEnv("anify-backend" /* Process.BACKEND */); - await promptEnv("anify-backend" /* Process.BACKEND */, backend); - const frontend = await parseEnv("anify-frontend" /* Process.FRONTEND */); - await promptEnv("anify-frontend" /* Process.FRONTEND */, frontend); - const auth = await parseEnv("anify-auth" /* Process.AUTH */); - await promptEnv("anify-auth" /* Process.AUTH */, auth); - const manager = await parseEnv("anify-manager" /* Process.MANAGER */); - await promptEnv("anify-manager" /* Process.MANAGER */, manager); - console.log(colors_1.default.green("Successfully setup environment variables.")); -} -exports.promptEnvVariables = promptEnvVariables; -async function parseEnv(process) { - const required = await (0, loadEnv_1.loadRequiredEnv)(process); - const current = await (0, loadEnv_1.loadEnv)(process); - // Check if all required environment variables are present - const missing = required.filter((key) => !current[key]); - if (missing.length > 0) { - console.error(colors_1.default.red(`Missing required environment variables: ${colors_1.default.yellow(missing.join(", "))} for ${colors_1.default.yellow(process)}.`)); - return missing; - } - else { - console.log(colors_1.default.green("All required environment variables are present for ") + colors_1.default.yellow(process) + colors_1.default.green(".")); - return []; - } -} -exports.parseEnv = parseEnv; -async function promptEnv(process, missing) { - // Prompt the user for the missing environment variables - const env = await (0, loadEnv_1.loadEnv)(process); - if (missing.length === 0) { - return; - } - console.log("\n"); - console.log(colors_1.default.bold(colors_1.default.yellow("Please enter the following environment variables:"))); - for (const key of missing) { - const value = await inquirer.prompt({ - type: "input", - name: key, - message: "Enter a value for " + colors_1.default.yellow(key) + ". Leave blank for none:", - default: env[key] ?? "", - }); - if (!value[key] || String(value[key]).trim() === "") { - delete env[key]; - continue; - } - let parsedValue = value[key]; - parsedValue = typeof parsedValue === "number" || typeof parsedValue === "boolean" ? parsedValue : parsedValue.startsWith('"') && parsedValue.endsWith('"') ? parsedValue.slice(1, -1) : parsedValue; - if (String(parsedValue)?.toLowerCase() === "true") { - parsedValue = true; - } - else if (String(parsedValue)?.toLowerCase() === "false") { - parsedValue = false; - } - else if (!isNaN(Number(parsedValue))) { - parsedValue = Number(parsedValue); - } - env[key] = parsedValue; - } - // Write the environment variables to the .env file - await (0, promises_1.writeFile)(`../${process}/.env`, Object.entries(env).map(([key, value]) => `${key}=${`"${value}"`}`).join("\n")); - console.log(colors_1.default.green("Successfully wrote environment variables to ") + colors_1.default.yellow(`../${process}/.env`) + colors_1.default.green(".")); - console.log("\n"); -} -exports.promptEnv = promptEnv; diff --git a/anify-cli/dist/prompts/frontend.d.ts b/anify-cli/dist/prompts/frontend.d.ts deleted file mode 100644 index 1441e11..0000000 --- a/anify-cli/dist/prompts/frontend.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function promptFrontend(): Promise; diff --git a/anify-cli/dist/prompts/frontend.js b/anify-cli/dist/prompts/frontend.js deleted file mode 100644 index e872b21..0000000 --- a/anify-cli/dist/prompts/frontend.js +++ /dev/null @@ -1,21 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.promptFrontend = void 0; -const colors_1 = __importDefault(require("colors")); -const env_1 = require("./env"); -const build_1 = require("../lib/build"); -async function promptFrontend() { - console.log(colors_1.default.yellow("Parsing environment variables...")); - const frontend = await (0, env_1.parseEnv)("anify-frontend" /* Process.FRONTEND */); - await (0, env_1.promptEnv)("anify-frontend" /* Process.FRONTEND */, frontend); - // Test out installing and building - const buildData = await (0, build_1.build)("anify-frontend" /* Process.FRONTEND */); - if (!buildData) { - return; - } - console.log(colors_1.default.green("Build succeeded. Frontend server is all setup.")); -} -exports.promptFrontend = promptFrontend; diff --git a/anify-cli/dist/prompts/manager.d.ts b/anify-cli/dist/prompts/manager.d.ts deleted file mode 100644 index 632bc90..0000000 --- a/anify-cli/dist/prompts/manager.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function promptManager(): Promise; diff --git a/anify-cli/dist/prompts/manager.js b/anify-cli/dist/prompts/manager.js deleted file mode 100644 index b8e38ca..0000000 --- a/anify-cli/dist/prompts/manager.js +++ /dev/null @@ -1,21 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.promptManager = void 0; -const colors_1 = __importDefault(require("colors")); -const env_1 = require("./env"); -const build_1 = require("../lib/build"); -async function promptManager() { - console.log(colors_1.default.yellow("Parsing environment variables...")); - const manager = await (0, env_1.parseEnv)("anify-manager" /* Process.MANAGER */); - await (0, env_1.promptEnv)("anify-manager" /* Process.MANAGER */, manager); - // Test out installing and building - const buildData = await (0, build_1.build)("anify-manager" /* Process.MANAGER */); - if (!buildData) { - return; - } - console.log(colors_1.default.green("Build succeeded. Manager is all setup.")); -} -exports.promptManager = promptManager; diff --git a/anify-cli/dist/types/index.d.ts b/anify-cli/dist/types/index.d.ts deleted file mode 100644 index 045cee0..0000000 --- a/anify-cli/dist/types/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export declare const enum Process { - FRONTEND = "anify-frontend", - BACKEND = "anify-backend", - AUTH = "anify-auth", - MANAGER = "anify-manager" -} diff --git a/anify-cli/dist/types/index.js b/anify-cli/dist/types/index.js deleted file mode 100644 index c8ad2e5..0000000 --- a/anify-cli/dist/types/index.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/anify-cli/package-lock.json b/anify-cli/package-lock.json deleted file mode 100644 index 82cab6b..0000000 --- a/anify-cli/package-lock.json +++ /dev/null @@ -1,4600 +0,0 @@ -{ - "name": "anify-cli", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "anify-cli", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "colors": "^1.4.0", - "commander": "^11.0.0", - "crypto-js": "^4.1.1", - "dotenv": "^16.0.3", - "inquirer": "^8.2.6" - }, - "devDependencies": { - "@types/node": "^18.16.2", - "@typescript-eslint/eslint-plugin": "^5.59.2", - "prettier": "2.8.8", - "prisma": "^4.13.0", - "prisma-json-types-generator": "^2.3.1", - "rimraf": "^5.0.0", - "ts-node": "^10.9.1", - "tsconfig-paths": "^4.2.0", - "tscpaths": "^0.0.9", - "tslib": "^2.5.0", - "typescript": "^4.9.5" - } - }, - "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/@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, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", - "dev": true, - "peer": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.2", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", - "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", - "dev": true, - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", - "dev": true, - "peer": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true, - "peer": true - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "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/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.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/@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "dependencies": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "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, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "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, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@prisma/debug": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-4.14.0.tgz", - "integrity": "sha512-K3yFVN3BZRCoSwit0uFAXSFlt3lz6iKJqPPZMuEH6n7zCFRBoQJhDT+QiMIfMdf6eOy4f0H4yK0KFRnx4TJA7Q==", - "dev": true, - "dependencies": { - "@types/debug": "4.1.7", - "debug": "4.3.4", - "strip-ansi": "6.0.1" - } - }, - "node_modules/@prisma/engines": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.14.0.tgz", - "integrity": "sha512-PDNlhP/1vyTgmNyiucGqGCdXIp7HIkkvKO50si3y3PcceeHvqtiKPaH1iJdz63jCWMVMbj2MElSxXPOeBvEVIQ==", - "dev": true, - "hasInstallScript": true - }, - "node_modules/@prisma/generator-helper": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.14.0.tgz", - "integrity": "sha512-cOULdYfbjxPqdN/ctHKYwqyjcOWaHxS4TuhvK9nCLFAgLh92VAla65aMgbmcqaynh1X6HVlGu0hLbHNACOqKRA==", - "dev": true, - "dependencies": { - "@prisma/debug": "4.14.0", - "@types/cross-spawn": "6.0.2", - "cross-spawn": "7.0.3", - "kleur": "4.1.5" - } - }, - "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.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "node_modules/@types/cross-spawn": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", - "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", - "dev": true, - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, - "node_modules/@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.16.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.6.tgz", - "integrity": "sha512-N7KINmeB8IN3vRR8dhgHEp+YpWvGFcpDoh5XZ8jB5a00AdFKCKEyyGTOPTddUf4JqU1ZKTVxkOxakDvchNVI2Q==", - "dev": true - }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz", - "integrity": "sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/type-utils": "5.59.5", - "@typescript-eslint/utils": "5.59.5", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz", - "integrity": "sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/typescript-estree": "5.59.5", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", - "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz", - "integrity": "sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.5", - "@typescript-eslint/utils": "5.59.5", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", - "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", - "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.5.tgz", - "integrity": "sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/typescript-estree": "5.59.5", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", - "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.5", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peer": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "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, - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "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==", - "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==", - "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==", - "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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "peer": true - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "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": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "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/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/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "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.1.13" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true - }, - "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, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", - "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==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/commander": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", - "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", - "engines": { - "node": ">=16" - } - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "engines": { - "node": ">=0.10.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, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "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, - "peer": true - }, - "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==", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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, - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "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, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", - "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.40.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", - "dev": true, - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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, - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", - "dev": true, - "peer": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "peer": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/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, - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "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, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/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, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "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, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.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==", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "peer": true - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "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", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "peer": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "peer": true - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "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==", - "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, - "peer": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "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, - "peer": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "peer": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true, - "peer": true - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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, - "peer": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", - "dev": true - }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "peer": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "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/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "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, - "peer": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "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, - "peer": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "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==", - "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/inquirer/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==" - }, - "node_modules/inquirer/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==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/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==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "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==", - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "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==", - "engines": { - "node": ">=8" - } - }, - "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-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, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jackspeak": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", - "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true, - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "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, - "peer": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "peer": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "peer": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "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, - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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, - "peer": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "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, - "peer": 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==", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "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/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "peer": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "peer": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.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==", - "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/ora/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==", - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "peer": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "peer": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "peer": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "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, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", - "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "peer": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prisma": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.14.0.tgz", - "integrity": "sha512-+5dMl1uxMQb4RepndY6AwR9xi1cDcaGFICu+ws6/Nmgt93mFPNj8tYxSfTdmfg+rkNrUId9rk/Ac2vTgLe/oXA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@prisma/engines": "4.14.0" - }, - "bin": { - "prisma": "build/index.js", - "prisma2": "build/index.js" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/prisma-json-types-generator": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-2.4.0.tgz", - "integrity": "sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg==", - "dev": true, - "dependencies": { - "@prisma/generator-helper": "^4.10.1", - "tslib": "^2.5.0" - }, - "bin": { - "prisma-json-types-generator": "dist/bin.js" - }, - "engines": { - "node": ">=14.0" - }, - "funding": { - "url": "https://github.com/ArthurFiorette/prisma-json-types-generator?sponsor=1" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "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==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "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==", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "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, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", - "dev": true, - "dependencies": { - "glob": "^10.2.5" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "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" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz", - "integrity": "sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.0", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "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==", - "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==", - "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": { - "queue-microtask": "^1.2.2" - } - }, - "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==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "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==", - "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/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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==" - }, - "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/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "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-width-cjs/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/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "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==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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/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, - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "peer": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "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/tscpaths": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/tscpaths/-/tscpaths-0.0.9.tgz", - "integrity": "sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w==", - "dev": true, - "dependencies": { - "commander": "^2.20.0", - "globby": "^9.2.0" - }, - "bin": { - "tscpaths": "cjs/index.js" - } - }, - "node_modules/tscpaths/node_modules/@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tscpaths/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/tscpaths/node_modules/dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "dependencies": { - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tscpaths/node_modules/fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "dependencies": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/tscpaths/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/tscpaths/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tscpaths/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/tscpaths/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tscpaths/node_modules/path-type/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tscpaths/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tscpaths/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "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, - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "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, - "peer": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "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/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "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, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "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, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/anify-cli/package.json b/anify-cli/package.json deleted file mode 100644 index d3d161d..0000000 --- a/anify-cli/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "devDependencies": { - "@types/node": "^18.16.2", - "@typescript-eslint/eslint-plugin": "^5.59.2", - "prettier": "2.8.8", - "prisma": "^4.13.0", - "prisma-json-types-generator": "^2.3.1", - "rimraf": "^5.0.0", - "ts-node": "^10.9.1", - "tsconfig-paths": "^4.2.0", - "tscpaths": "^0.0.9", - "tslib": "^2.5.0", - "typescript": "^4.9.5" - }, - "name": "anify-cli", - "description": "CLI for Anify", - "version": "1.0.0", - "source": "src/index.ts", - "scripts": { - "dev": "ts-node -r tsconfig-paths/register src/index.ts", - "cli": "npm start", - "start": "node dist/index.js", - "build": "npm run build:ts && npm run lint", - "build:ts": "tsc --project tsconfig.json && tscpaths -p tsconfig.json -s ./src -o ./dist", - "clean": "rimraf dist/", - "eslint": "eslint --ext .ts src/** --fix", - "prettier": "prettier --write .", - "lint": "npm run prettier && npm run eslint" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Eltik/Anify.git" - }, - "author": "eltik", - "license": "ISC", - "bugs": { - "url": "https://github.com/Eltik/Anify/issues" - }, - "homepage": "https://github.com/Eltik/Anify#readme", - "dependencies": { - "colors": "^1.4.0", - "commander": "^11.0.0", - "crypto-js": "^4.1.1", - "dotenv": "^16.0.3", - "inquirer": "^8.2.6" - } -} diff --git a/anify-cli/src/index.ts b/anify-cli/src/index.ts deleted file mode 100644 index e715abb..0000000 --- a/anify-cli/src/index.ts +++ /dev/null @@ -1,71 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import { program } from "commander"; -import * as inquirer from "inquirer"; -import { promptEnvVariables } from "./prompts/env"; -import { promptBackend } from "./prompts/backend"; -import { promptFrontend } from "./prompts/frontend"; -import { promptAuth } from "./prompts/auth"; -import { promptManager } from "./prompts/manager"; - -program.description("A robust CLI for creating a web server for anime, manga, and light novels.") - .option("-e, -enviornment", "Setup the environment variables.") - .option("-b, -backend", "Setup the backend.") - .option("-f, -frontend", "Setup the frontend.") - .option("-a, -auth", "Setup the authentication.") - .option("-m, -manager", "Setup the manager."); - -program.parse() - -const options = program.opts(); - - if (options.e) { - promptEnvVariables(); -} else if (options.b) { - promptBackend(); -} else if (options.f) { - promptFrontend(); -} else if (options.a) { - promptAuth(); -} else if (options.m) { - promptManager(); -} else { - promptSetup(); -} - -async function promptSetup() { - const { type } = await inquirer.prompt({ - type: "list", - name: "type", - message: "What setup are you looking for?", - choices: [ - "Environmental Variables", - "Backend", - "Frontend", - "Authentication", - "Manager" - ], - default: "Anime", - }); - - switch (type) { - case "Environmental Variables": - await promptEnvVariables(); - break; - case "Backend": - await promptBackend(); - break; - case "Frontend": - await promptFrontend(); - break; - case "Authentication": - await promptAuth(); - break; - case "Manager": - await promptManager(); - break; - default: - break; - } -} \ No newline at end of file diff --git a/anify-cli/src/lib/build.ts b/anify-cli/src/lib/build.ts deleted file mode 100644 index af4f267..0000000 --- a/anify-cli/src/lib/build.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Process } from "../types"; -import childProcess from "child_process"; -import colors from "colors"; - -const simulateLoadingDots = () => { - const dots = ['.', '..', '...']; - let i = 0; - - const interval = setInterval(() => { - process.stdout.clearLine(0); - process.stdout.cursorTo(0); - process.stdout.write("\x1B[?25l"); // Hide cursor - process.stdout.write(colors.cyan(`Building${dots[i]}\r`)); - - if (i === dots.length - 1) { - i = 0; - } else { - i++; - } - - }, 500); - - return interval; -}; - - -export const build = async (process: Process) => { - const child = childProcess.spawn("npm", ["run", "build"], { - cwd: `../${process}`, - stdio: "pipe" - }); - - const loadingInterval = simulateLoadingDots(); - - return new Promise((resolve, reject) => { - let buildOutput = ""; // Variable to capture build output - - child.stdout?.on("data", (data) => { - buildOutput += data.toString(); - }); - - child.stderr?.on("data", (data) => { - buildOutput += data.toString(); - }); - - child.on("error", (error) => { - clearInterval(loadingInterval); - console.error(colors.red(`Error starting build process: ${error.message}\n`)); - resolve(false); - }); - - child.on("exit", (code) => { - clearInterval(loadingInterval); - - if (code === 0) { - console.log(colors.green("Build completed successfully\n")); - resolve(true); - } else { - console.error(buildOutput); // Log the error output - console.log(colors.red("Build failed. Please check the above for errors.\n")); - resolve(false); - } - }); - }); -}; \ No newline at end of file diff --git a/anify-cli/src/lib/loadEnv.ts b/anify-cli/src/lib/loadEnv.ts deleted file mode 100644 index 1a72799..0000000 --- a/anify-cli/src/lib/loadEnv.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { readFile } from "fs/promises"; -import { Process } from "../types"; -import { existsSync } from "fs"; - -export const loadRequiredEnv = async (process: Process) => { - if (!existsSync(`../${process}/.env.example`)) { - return []; - } - - const env = await readFile(`../${process}/.env.example`, "utf-8"); - // Convert to JSON - const envVariables: Record = {}; - - env.split("\n").forEach((line) => { - if (line.startsWith("#")) { - // Ignore comments - return; - } - - const [key, value] = line.split("="); - if (!key || !value) { - return; - } - - // Try to parse values into appropriate types - let parsedValue: string | boolean | number = value.trim(); - parsedValue = parsedValue.startsWith('"') && parsedValue.endsWith('"') ? parsedValue.slice(1, -1) : parsedValue; - - if (parsedValue?.toLowerCase() === "true") { - parsedValue = true; - } else if (parsedValue?.toLowerCase() === "false") { - parsedValue = false; - } else if (!isNaN(Number(parsedValue))) { - parsedValue = Number(parsedValue); - } - - envVariables[key] = parsedValue; - }); - - // Return the keys - return Object.keys(envVariables); -}; - -export const loadEnv = async (process: Process) => { - if (!existsSync(`../${process}/.env`)) { - return {}; - } - - const env = await readFile(`../${process}/.env`, "utf-8"); - // Convert to JSON - const envVariables: Record = {}; - - env.split("\n").forEach((line) => { - if (line.startsWith("#")) { - // Ignore comments - return; - } - - const equalIndex = line.indexOf("="); - if (equalIndex === -1) { - // Skip lines without '=' - return; - } - - const key = line.slice(0, equalIndex).trim(); - const value = line.slice(equalIndex + 1).trim(); - - // Try to parse values into appropriate types - let parsedValue: string | boolean | number = value.trim(); - parsedValue = parsedValue.startsWith('"') ? parsedValue.slice(1) : parsedValue; - parsedValue = parsedValue.endsWith('"') ? parsedValue.slice(0, -1) : parsedValue; - - if (parsedValue?.toLowerCase() === "true") { - parsedValue = true; - } else if (parsedValue?.toLowerCase() === "false") { - parsedValue = false; - } else if (!isNaN(Number(parsedValue))) { - parsedValue = Number(parsedValue); - } - - envVariables[key] = parsedValue; - }); - - return envVariables; -}; diff --git a/anify-cli/src/prompts/auth.ts b/anify-cli/src/prompts/auth.ts deleted file mode 100644 index 42064de..0000000 --- a/anify-cli/src/prompts/auth.ts +++ /dev/null @@ -1,21 +0,0 @@ -import colors from "colors"; -import { parseEnv, promptEnv } from "./env"; -import { Process } from "../types"; -import { build } from "../lib/build"; - -export async function promptAuth() { - console.log(colors.yellow("Parsing environment variables...")); - - const auth = await parseEnv(Process.AUTH); - await promptEnv(Process.AUTH, auth); - - // Test out installing and building - const buildData = await build(Process.AUTH); - - if (!buildData) { - console.log(colors.red("Build failed. Please check the above for errors.\n")); - return; - } - - console.log(colors.green("Build succeeded. Authentication server is all setup.")); -} \ No newline at end of file diff --git a/anify-cli/src/prompts/backend.ts b/anify-cli/src/prompts/backend.ts deleted file mode 100644 index 2ee12ab..0000000 --- a/anify-cli/src/prompts/backend.ts +++ /dev/null @@ -1,19 +0,0 @@ -import colors from "colors"; -import { parseEnv, promptEnv } from "./env"; -import { Process } from "../types"; -import { build } from "../lib/build"; - -export async function promptBackend() { - console.log(colors.yellow("Parsing environment variables...")); - - const backend = await parseEnv(Process.BACKEND); - await promptEnv(Process.BACKEND, backend); - - // Test out installing and building - const buildData = await build(Process.BACKEND); - if (!buildData) { - return; - } - - console.log(colors.green("Build succeeded. Backend server is all setup.")); -} \ No newline at end of file diff --git a/anify-cli/src/prompts/env.ts b/anify-cli/src/prompts/env.ts deleted file mode 100644 index 63af6b1..0000000 --- a/anify-cli/src/prompts/env.ts +++ /dev/null @@ -1,84 +0,0 @@ -import * as inquirer from "inquirer"; -import colors from "colors"; -import { Process } from "../types"; -import { loadEnv, loadRequiredEnv } from "../lib/loadEnv"; -import { writeFile } from "fs/promises"; - -export async function promptEnvVariables() { - // Setup environment variables - console.log(colors.yellow("Parsing environment variables...")); - - const backend = await parseEnv(Process.BACKEND); - await promptEnv(Process.BACKEND, backend); - - const frontend = await parseEnv(Process.FRONTEND); - await promptEnv(Process.FRONTEND, frontend); - - const auth = await parseEnv(Process.AUTH); - await promptEnv(Process.AUTH, auth); - - const manager = await parseEnv(Process.MANAGER); - await promptEnv(Process.MANAGER, manager); - - console.log(colors.green("Successfully setup environment variables.")); -} - -export async function parseEnv(process: Process) { - const required = await loadRequiredEnv(process); - const current = await loadEnv(process); - - // Check if all required environment variables are present - const missing = required.filter((key) => !current[key]); - if (missing.length > 0) { - console.error(colors.red(`Missing required environment variables: ${colors.yellow(missing.join(", "))} for ${colors.yellow(process)}.`)); - return missing; - } else { - console.log(colors.green("All required environment variables are present for ") + colors.yellow(process) + colors.green(".")); - return []; - } -} - -export async function promptEnv(process: Process, missing: string[]) { - // Prompt the user for the missing environment variables - const env = await loadEnv(process); - - if (missing.length === 0) { - return; - } - - console.log("\n"); - - console.log(colors.bold(colors.yellow("Please enter the following environment variables:"))); - for (const key of missing) { - const value = await inquirer.prompt({ - type: "input", - name: key, - message: "Enter a value for " + colors.yellow(key) + ". Leave blank for none:", - default: env[key] ?? "", - }); - - if (!value[key] || String(value[key]).trim() === "") { - delete env[key]; - continue; - } - - let parsedValue: string | boolean | number = value[key]; - parsedValue = typeof parsedValue === "number" || typeof parsedValue === "boolean" ? parsedValue : parsedValue.startsWith('"') && parsedValue.endsWith('"') ? parsedValue.slice(1, -1) : parsedValue; - - if (String(parsedValue)?.toLowerCase() === "true") { - parsedValue = true; - } else if (String(parsedValue)?.toLowerCase() === "false") { - parsedValue = false; - } else if (!isNaN(Number(parsedValue))) { - parsedValue = Number(parsedValue); - } - - env[key] = parsedValue; - } - - // Write the environment variables to the .env file - await writeFile(`../${process}/.env`, Object.entries(env).map(([key, value]) => `${key}=${`"${value}"`}`).join("\n")); - console.log(colors.green("Successfully wrote environment variables to ") + colors.yellow(`../${process}/.env`) + colors.green(".")); - - console.log("\n"); -} \ No newline at end of file diff --git a/anify-cli/src/prompts/frontend.ts b/anify-cli/src/prompts/frontend.ts deleted file mode 100644 index 9bc1dc0..0000000 --- a/anify-cli/src/prompts/frontend.ts +++ /dev/null @@ -1,19 +0,0 @@ -import colors from "colors"; -import { parseEnv, promptEnv } from "./env"; -import { Process } from "../types"; -import { build } from "../lib/build"; - -export async function promptFrontend() { - console.log(colors.yellow("Parsing environment variables...")); - - const frontend = await parseEnv(Process.FRONTEND); - await promptEnv(Process.FRONTEND, frontend); - - // Test out installing and building - const buildData = await build(Process.FRONTEND); - if (!buildData) { - return; - } - - console.log(colors.green("Build succeeded. Frontend server is all setup.")); -} \ No newline at end of file diff --git a/anify-cli/src/prompts/manager.ts b/anify-cli/src/prompts/manager.ts deleted file mode 100644 index f022ca3..0000000 --- a/anify-cli/src/prompts/manager.ts +++ /dev/null @@ -1,19 +0,0 @@ -import colors from "colors"; -import { parseEnv, promptEnv } from "./env"; -import { Process } from "../types"; -import { build } from "../lib/build"; - -export async function promptManager() { - console.log(colors.yellow("Parsing environment variables...")); - - const manager = await parseEnv(Process.MANAGER); - await promptEnv(Process.MANAGER, manager); - - // Test out installing and building - const buildData = await build(Process.MANAGER); - if (!buildData) { - return; - } - - console.log(colors.green("Build succeeded. Manager is all setup.")); -} \ No newline at end of file diff --git a/anify-cli/src/types/index.ts b/anify-cli/src/types/index.ts deleted file mode 100644 index 99f612f..0000000 --- a/anify-cli/src/types/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const enum Process { - FRONTEND = "anify-frontend", - BACKEND = "anify-backend", - AUTH = "anify-auth", - MANAGER = "anify-manager" -} diff --git a/anify-cli/tsconfig.json b/anify-cli/tsconfig.json deleted file mode 100644 index f3b9dff..0000000 --- a/anify-cli/tsconfig.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "compilerOptions": { - "target": "esnext", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "esModuleInterop": true, - "module": "CommonJS", - "moduleResolution": "node", - "resolveJsonModule": true, - "noImplicitAny": false, - "isolatedModules": false, - "allowSyntheticDefaultImports": true, - "jsx": "preserve", - "incremental": true, - "declaration": true, - "baseUrl": ".", - "paths": { - "@/*": ["./*"], - "database": ["./src/database"] - }, - "outDir": "./dist" - }, - "include": ["src"], - "exclude": ["node_modules", "dist"], - "ts-node": { - "compilerOptions": { - "module": "commonjs" - } - } -} diff --git a/anify-cli/yarn.lock b/anify-cli/yarn.lock deleted file mode 100644 index 84ea73e..0000000 --- a/anify-cli/yarn.lock +++ /dev/null @@ -1,2345 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@cspotcode/source-map-support@^0.8.0": - 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== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - -"@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.5.2" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.40.0": - version "8.40.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz" - integrity sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA== - -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@jridgewell/resolve-uri@^3.0.3": - 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== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@prisma/debug@4.14.0": - version "4.14.0" - resolved "https://registry.npmjs.org/@prisma/debug/-/debug-4.14.0.tgz" - integrity sha512-K3yFVN3BZRCoSwit0uFAXSFlt3lz6iKJqPPZMuEH6n7zCFRBoQJhDT+QiMIfMdf6eOy4f0H4yK0KFRnx4TJA7Q== - dependencies: - "@types/debug" "4.1.7" - debug "4.3.4" - strip-ansi "6.0.1" - -"@prisma/engines@4.14.0": - version "4.14.0" - resolved "https://registry.npmjs.org/@prisma/engines/-/engines-4.14.0.tgz" - integrity sha512-PDNlhP/1vyTgmNyiucGqGCdXIp7HIkkvKO50si3y3PcceeHvqtiKPaH1iJdz63jCWMVMbj2MElSxXPOeBvEVIQ== - -"@prisma/generator-helper@^4.10.1": - version "4.14.0" - resolved "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.14.0.tgz" - integrity sha512-cOULdYfbjxPqdN/ctHKYwqyjcOWaHxS4TuhvK9nCLFAgLh92VAla65aMgbmcqaynh1X6HVlGu0hLbHNACOqKRA== - dependencies: - "@prisma/debug" "4.14.0" - "@types/cross-spawn" "6.0.2" - cross-spawn "7.0.3" - kleur "4.1.5" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== - -"@types/cross-spawn@6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz" - integrity sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw== - dependencies: - "@types/node" "*" - -"@types/debug@4.1.7": - version "4.1.7" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== - dependencies: - "@types/ms" "*" - -"@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/minimatch@*": - version "5.1.2" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - -"@types/ms@*": - version "0.7.31" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/node@*", "@types/node@^18.16.2": - version "18.16.6" - resolved "https://registry.npmjs.org/@types/node/-/node-18.16.6.tgz" - integrity sha512-N7KINmeB8IN3vRR8dhgHEp+YpWvGFcpDoh5XZ8jB5a00AdFKCKEyyGTOPTddUf4JqU1ZKTVxkOxakDvchNVI2Q== - -"@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@typescript-eslint/eslint-plugin@^5.59.2": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz" - integrity sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.5" - "@typescript-eslint/type-utils" "5.59.5" - "@typescript-eslint/utils" "5.59.5" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.0.0": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz" - integrity sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw== - dependencies: - "@typescript-eslint/scope-manager" "5.59.5" - "@typescript-eslint/types" "5.59.5" - "@typescript-eslint/typescript-estree" "5.59.5" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz" - integrity sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A== - dependencies: - "@typescript-eslint/types" "5.59.5" - "@typescript-eslint/visitor-keys" "5.59.5" - -"@typescript-eslint/type-utils@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz" - integrity sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg== - dependencies: - "@typescript-eslint/typescript-estree" "5.59.5" - "@typescript-eslint/utils" "5.59.5" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz" - integrity sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w== - -"@typescript-eslint/typescript-estree@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz" - integrity sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg== - dependencies: - "@typescript-eslint/types" "5.59.5" - "@typescript-eslint/visitor-keys" "5.59.5" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.5.tgz" - integrity sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.5" - "@typescript-eslint/types" "5.59.5" - "@typescript-eslint/typescript-estree" "5.59.5" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz" - integrity sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA== - dependencies: - "@typescript-eslint/types" "5.59.5" - eslint-visitor-keys "^3.3.0" - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.4.1, acorn@^8.8.0: - version "8.8.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" - integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" - integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== - -array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" - integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== - dependencies: - array-uniq "^1.0.1" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" - integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" - integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bl@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -call-me-maybe@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz" - integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-spinners@^2.5.0: - version "2.9.0" - resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz" - integrity sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g== - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" - integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colors@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -commander@^11.0.0: - version "11.0.0" - resolved "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz" - integrity sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" - integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-js@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz" - integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== - -debug@^2.2.0: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^2.3.3: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decode-uri-component@^0.2.0: - version "0.2.2" - resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" - integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== - -deep-is@^0.1.3: - 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== - -defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz" - integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== - dependencies: - clone "^1.0.2" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" - integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" - integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz" - integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== - dependencies: - path-type "^3.0.0" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dotenv@^16.0.3: - version "16.0.3" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz" - integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint@*, "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0": - version "8.40.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz" - integrity sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.40.0" - "@humanwhocodes/config-array" "^0.11.8" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.5.2" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-sdsl "^4.1.4" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== - dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" - integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - 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== - -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - 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" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" - integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" - integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== - -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" - integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== - dependencies: - map-cache "^0.2.2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" - integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz" - integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz" - integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== - -glob@^10.2.5: - version "10.2.5" - resolved "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz" - integrity sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.0.3" - minimatch "^9.0.0" - minipass "^5.0.0 || ^6.0.2" - path-scurry "^1.7.0" - -glob@^7.1.3: - version "7.2.3" - 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" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - 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" - -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" - integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" - integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" - integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" - integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.3: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - 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" - -inherits@^2.0.3, inherits@^2.0.4, inherits@2: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inquirer@^8.2.6: - version "8.2.6" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz" - integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== - 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" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" - integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - 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== - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz" - integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-interactive@^1.0.0: - 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== - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" - integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== - dependencies: - kind-of "^3.0.2" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - 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== - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -isarray@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" - integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -jackspeak@^2.0.3: - version "2.2.0" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz" - integrity sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -js-sdsl@^4.1.4: - version "4.4.0" - resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz" - integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^2.2.2: - version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -kind-of@^3.0.2, kind-of@^3.0.3: - version "3.2.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" - integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kleur@4.1.5: - version "4.1.5" - resolved "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz" - integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -lru-cache@^6.0.0: - 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" - -lru-cache@^9.1.1: - version "9.1.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz" - integrity sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A== - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" - integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== - dependencies: - object-visit "^1.0.0" - -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^3.1.10: - version "3.1.10" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - 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" - -minimatch@^9.0.0: - version "9.0.0" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz" - integrity sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -"minipass@^5.0.0 || ^6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" - integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" - integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== - dependencies: - isobject "^3.0.0" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" - integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== - dependencies: - isobject "^3.0.1" - -once@^1.3.0: - 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" - -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - 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" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - 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== - dependencies: - p-limit "^3.0.2" - -parent-module@^1.0.0: - 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== - dependencies: - callsites "^3.0.0" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" - integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz" - integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-scurry@^1.7.0: - version "1.9.2" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz" - integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg== - dependencies: - lru-cache "^9.1.1" - minipass "^5.0.0 || ^6.0.2" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" - integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier@2.8.8: - version "2.8.8" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -prisma-json-types-generator@^2.3.1: - version "2.4.0" - resolved "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-2.4.0.tgz" - integrity sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg== - dependencies: - "@prisma/generator-helper" "^4.10.1" - tslib "^2.5.0" - -prisma@^4.13.0: - version "4.14.0" - resolved "https://registry.npmjs.org/prisma/-/prisma-4.14.0.tgz" - integrity sha512-+5dMl1uxMQb4RepndY6AwR9xi1cDcaGFICu+ws6/Nmgt93mFPNj8tYxSfTdmfg+rkNrUId9rk/Ac2vTgLe/oXA== - dependencies: - "@prisma/engines" "4.14.0" - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -readable-stream@^3.4.0: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" - integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rimraf@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz" - integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== - dependencies: - glob "^10.2.5" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rxjs@^7.5.5: - version "7.8.1" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== - dependencies: - tslib "^2.1.0" - -safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" - integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -semver@^7.3.7: - version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^3.0.2: - version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz" - integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" - integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -string_decoder@^1.1.1: - 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== - dependencies: - safe-buffer "~5.2.0" - -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1, strip-ansi@6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - 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== - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" - integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" - integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex-range@^5.0.1: - 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== - dependencies: - is-number "^7.0.0" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -ts-node@^10.9.1: - version "10.9.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - 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" - -tsconfig-paths@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tscpaths@^0.0.9: - version "0.0.9" - resolved "https://registry.npmjs.org/tscpaths/-/tscpaths-0.0.9.tgz" - integrity sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w== - dependencies: - commander "^2.20.0" - globby "^9.2.0" - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.1.0, tslib@^2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.20.2: - 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== - -type-fest@^0.21.3: - 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== - -typescript@^4.9.5, typescript@>=2.7, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": - version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" - integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" - integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -v8-compile-cache-lib@^3.0.1: - 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== - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@^1.2.3: - version "1.2.4" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz" - integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^6.0.1: - version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/anify-manager-recode/.eslintignore b/anify-manager-recode/.eslintignore deleted file mode 100644 index 7d671e7..0000000 --- a/anify-manager-recode/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -/dist -**/*.js \ No newline at end of file diff --git a/anify-manager-recode/.eslintrc b/anify-manager-recode/.eslintrc deleted file mode 100644 index 13b5ac5..0000000 --- a/anify-manager-recode/.eslintrc +++ /dev/null @@ -1,33 +0,0 @@ -{ - "parser": "@typescript-eslint/parser", - "plugins": [ - "@typescript-eslint" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "rules": { - "@typescript-eslint/ban-types": "warn", - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-empty-function": "off", - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-namespace": "off", - "@typescript-eslint/no-loss-of-precision": "off", - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-non-null-asserted-optional-chain": "off", - "@typescript-eslint/no-unnecessary-type-constraint": "warn", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/no-var-requires": "warn", - "no-console": "off", - "no-empty": "warn", - "no-prototype-builtins": "off", - "no-redeclare": "warn", - "no-useless-escape": "off", - "no-async-promise-executor": "off", - "prefer-const": "warn", - "array-bracket-spacing": ["error", "never"] - } -} \ No newline at end of file diff --git a/anify-manager-recode/.prettierignore b/anify-manager-recode/.prettierignore deleted file mode 100644 index eeda442..0000000 --- a/anify-manager-recode/.prettierignore +++ /dev/null @@ -1,12 +0,0 @@ -node_modules -*.js -*.d.ts -*.md -*.json -*.lock -*.yml -*.yaml -Dockerfile -Dockerfile.* -.eslintrc -*.html \ No newline at end of file diff --git a/anify-manager-recode/.prettierrc.json b/anify-manager-recode/.prettierrc.json deleted file mode 100644 index 0e41e21..0000000 --- a/anify-manager-recode/.prettierrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "useTabs": false, - "tabWidth": 4, - "semi": true, - "singleQuote": false, - "bracketSpacing": true, - "bracketSameLine": false, - "arrowParens": "always", - "parser": "typescript", - "printWidth": 10000, - "proseWrap": "never", - "endOfLine": "lf" -} diff --git a/anify-manager-recode/package.json b/anify-manager-recode/package.json deleted file mode 100644 index 102bc54..0000000 --- a/anify-manager-recode/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "anify-manager-recode", - "module": "index.ts", - "type": "module", - "scripts": { - "start": "bun run dist/index.js", - "dev": "bun run src/index.ts", - "build": "bun build ./src/index.ts --outdir ./dist --target node", - "prettier": "prettier --write .", - "eslint": "eslint --ext .ts src/** --fix", - "lint": "bun run prettier && bun run eslint" - }, - "devDependencies": { - "@typescript-eslint/eslint-plugin": "^6.7.0", - "@typescript-eslint/parser": "^6.7.0", - "bun-types": "latest", - "eslint": "^8.49.0" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "dependencies": { - "colors": "^1.4.0", - "eris": "^0.17.2", - "pm2": "^5.3.0" - } -} \ No newline at end of file diff --git a/anify-manager-recode/src/index.ts b/anify-manager-recode/src/index.ts deleted file mode 100644 index 475e325..0000000 --- a/anify-manager-recode/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -import "./discord/client"; diff --git a/anify-manager-recode/src/utils/pm2/initalizePm2.ts b/anify-manager-recode/src/utils/pm2/initalizePm2.ts deleted file mode 100644 index f0bad1d..0000000 --- a/anify-manager-recode/src/utils/pm2/initalizePm2.ts +++ /dev/null @@ -1,17 +0,0 @@ -import pm2 from "pm2"; - -let pm2Initilized: boolean = false; - -export default (): Promise => { - if (pm2Initilized) return Promise.resolve(); - return new Promise((resolve, reject) => { - pm2.connect((err) => { - if (err) { - console.error(err); - reject(err); - } - pm2Initilized = true; - resolve(); - }); - }); -}; diff --git a/anify-manager-recode/src/utils/pm2/list.ts b/anify-manager-recode/src/utils/pm2/list.ts deleted file mode 100644 index 6e756d6..0000000 --- a/anify-manager-recode/src/utils/pm2/list.ts +++ /dev/null @@ -1,27 +0,0 @@ -import pm2 from "pm2"; -import initalizePm2 from "./initalizePm2"; - -export interface IResponse extends Object { - error?: string; - data: { - name?: string; - pid?: number; - }[]; -} - -const list = async (): Promise => { - await initalizePm2(); - return new Promise((resolve, reject) => { - pm2.list((err, list) => { - if (err) { - console.error(err); - return resolve({ error: err.message, data: [] }); - } - - resolve({ data: list.map((x) => ({ name: x.name, pid: x.pid })) }); - }); - }); -}; - -export default list; -export { list }; diff --git a/anify-manager-recode/tsconfig.json b/anify-manager-recode/tsconfig.json deleted file mode 100644 index 388a057..0000000 --- a/anify-manager-recode/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "preserve", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} diff --git a/anify-manager/.env.example b/anify-manager/.env.example deleted file mode 100644 index a9cf078..0000000 --- a/anify-manager/.env.example +++ /dev/null @@ -1,14 +0,0 @@ -# Discord token -TOKEN="token_here" -# Discord client ID -CLIENT="123456" -# Discord guild ID -GUILD="123456" -# Frontend server URL (local is fine) -FRONTEND="http://localhost:3000" -# Backend server URL (local is fine) -API="http://localhost:3060" -# Authentication server URL (local is fine) -AUTH="http://localhost:3606" -# Backend API key -MASTER_KEY="123456" \ No newline at end of file diff --git a/anify-manager/.eslintignore b/anify-manager/.eslintignore index cf44e14..7d671e7 100644 --- a/anify-manager/.eslintignore +++ b/anify-manager/.eslintignore @@ -1 +1,2 @@ +/dist **/*.js \ No newline at end of file diff --git a/anify-manager-recode/.gitignore b/anify-manager/.gitignore similarity index 100% rename from anify-manager-recode/.gitignore rename to anify-manager/.gitignore diff --git a/anify-manager/.prettierignore b/anify-manager/.prettierignore index dffb4ad..eeda442 100644 --- a/anify-manager/.prettierignore +++ b/anify-manager/.prettierignore @@ -8,4 +8,5 @@ node_modules *.yaml Dockerfile Dockerfile.* -.eslintrc \ No newline at end of file +.eslintrc +*.html \ No newline at end of file diff --git a/anify-manager/READMD.md b/anify-manager/READMD.md deleted file mode 100644 index 67cdf63..0000000 --- a/anify-manager/READMD.md +++ /dev/null @@ -1,2 +0,0 @@ -# anify-manager -This documentation will be updated soon. \ No newline at end of file diff --git a/anify-manager-recode/README.md b/anify-manager/README.md similarity index 100% rename from anify-manager-recode/README.md rename to anify-manager/README.md diff --git a/anify-manager/dist/bot/channels.json b/anify-manager/dist/bot/channels.json deleted file mode 100644 index 81ae70b..0000000 --- a/anify-manager/dist/bot/channels.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "errorChannel": "951146206036373565", - "logChannel": "1034958914363600967", - "suggestions": "1041158741556461619", - "status": "1036751152768884856", - "api": "1132046237357588533" -} diff --git a/anify-manager/dist/bot/colors.json b/anify-manager/dist/bot/colors.json deleted file mode 100644 index e98cd79..0000000 --- a/anify-manager/dist/bot/colors.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": "#df5d5d", - "denied": "#ff6b6b", - "neutral": "#4cb875", - "success": "#84feb3" -} diff --git a/anify-manager/dist/bot/commands/assign.d.ts b/anify-manager/dist/bot/commands/assign.d.ts deleted file mode 100644 index 1ae382f..0000000 --- a/anify-manager/dist/bot/commands/assign.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CommandInteraction, SlashCommandBuilder } from "discord.js"; -declare const _default: { - data: Omit; - execute(interaction: CommandInteraction): Promise | undefined>; -}; -export default _default; diff --git a/anify-manager/dist/bot/commands/assign.js b/anify-manager/dist/bot/commands/assign.js deleted file mode 100644 index a19d9f1..0000000 --- a/anify-manager/dist/bot/commands/assign.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const colors_json_1 = __importDefault(require("../colors.json")); -const discord_js_1 = require("discord.js"); -const axios_1 = __importDefault(require("axios")); -const __1 = require(".."); -exports.default = { - data: new discord_js_1.SlashCommandBuilder() - .setName("assign") - .setDescription("Assigns an API key to an user.") - .addUserOption((option) => option.setName("user").setDescription("The user to assign the API key to").setRequired(true)) - .addStringOption((option) => option.setName("master-key").setDescription("Master key").setRequired(true)) - .addStringOption((option) => option.setName("key").setDescription("The key to assign").setRequired(true)), - async execute(interaction) { - const user = interaction.options.getUser("user"); - const master = interaction.options.get("master-key")?.value; - const key = interaction.options.get("key")?.value; - if (master != __1.masterKey) { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription("You don't have permission to run this command!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - if (!user) { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription("You didn't specify a user!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - try { - const { data } = await axios_1.default.get(`${__1.api}/assign?id=${user.id}&key=${key}&apikey=${master}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - if (data.error) { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription(JSON.stringify(data)) - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.success) - .setDescription(`Successfully assigned key \`${key}\` to <@${user.id}>!`) - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - await user.send(`Your API key has been assigned to \`${key}\`!`).catch((err) => { - interaction.channel?.send(`Failed to DM <@${user.id}>!`); - }); - } - catch (e) { - console.error(e); - await interaction.channel?.send("Error."); - } - }, -}; diff --git a/anify-manager/dist/bot/commands/get.d.ts b/anify-manager/dist/bot/commands/get.d.ts deleted file mode 100644 index a253cd2..0000000 --- a/anify-manager/dist/bot/commands/get.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CommandInteraction, SlashCommandBuilder } from "discord.js"; -declare const _default: { - data: SlashCommandBuilder; - execute(interaction: CommandInteraction): Promise | undefined>; -}; -export default _default; diff --git a/anify-manager/dist/bot/commands/get.js b/anify-manager/dist/bot/commands/get.js deleted file mode 100644 index 56d021f..0000000 --- a/anify-manager/dist/bot/commands/get.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const colors_json_1 = __importDefault(require("../colors.json")); -const discord_js_1 = require("discord.js"); -const axios_1 = __importDefault(require("axios")); -const __1 = require(".."); -exports.default = { - data: new discord_js_1.SlashCommandBuilder().setName("get").setDescription("Gets your personal API key."), - async execute(interaction) { - try { - const { data } = await axios_1.default.get(`${__1.api}/key?id=${interaction.member?.user.id}&apikey=${__1.masterKey}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - if (data.error) { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription(JSON.stringify(data)) - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - const string = ` - **Key**: \`${data.key}\` - **Request Count**: \`${data.requestCount}\` - **Created At**: \`${data.createdAt}\` - **Updated At**: \`${data.updatedAt}\` - `; - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setDescription(string) - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - } - catch (e) { - console.error(e); - await interaction.reply("Error."); - } - }, -}; diff --git a/anify-manager/dist/bot/commands/keys.d.ts b/anify-manager/dist/bot/commands/keys.d.ts deleted file mode 100644 index 1ae382f..0000000 --- a/anify-manager/dist/bot/commands/keys.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CommandInteraction, SlashCommandBuilder } from "discord.js"; -declare const _default: { - data: Omit; - execute(interaction: CommandInteraction): Promise | undefined>; -}; -export default _default; diff --git a/anify-manager/dist/bot/commands/keys.js b/anify-manager/dist/bot/commands/keys.js deleted file mode 100644 index 44eea31..0000000 --- a/anify-manager/dist/bot/commands/keys.js +++ /dev/null @@ -1,77 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const colors_json_1 = __importDefault(require("../colors.json")); -const discord_js_1 = require("discord.js"); -const axios_1 = __importDefault(require("axios")); -const __1 = require(".."); -exports.default = { - data: new discord_js_1.SlashCommandBuilder() - .setName("keys") - .setDescription("Gets API keys.") - .addStringOption((option) => option.setName("key").setDescription("Master key").setRequired(true)) - .addIntegerOption((option) => option.setName("page").setDescription("Page to view")), - async execute(interaction) { - const key = interaction.options.get("key")?.value; - let page = interaction.options.get("page")?.value ?? 1; - if (key != __1.masterKey) { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription("You don't have permission to run this command!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - try { - const { data } = await axios_1.default.get(`${__1.api}/keys?apikey=${key}`); - const pageSize = 5; // Number of items to display per page - const totalPages = Math.ceil(data.length / pageSize); - const pageContent = []; - for (let i = 0; i < data.length; i += pageSize) { - const pageKeys = data.slice(i, i + pageSize); - let string = ""; - for (const item of pageKeys) { - if (string.length !== 0) - string += "======"; - string += ` - **User**: <@${item.id}> - **Key**: \`${item.key}\` - **Request Count**: \`${item.requestCount}\` - **Created At**: \`${item.createdAt}\` - **Updated At**: \`${item.updatedAt}\` - `; - } - pageContent.push(string); - } - if (page > totalPages) - page = totalPages; - page = Math.max(1, Math.min(page, totalPages)); // Ensure page number is within valid range - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setTitle(`Admin Keys (Page ${page}/${totalPages})`) - .setDescription(pageContent[page - 1]) - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - } - catch (e) { - console.error(e); - await interaction.reply({ content: `Error executing command!`, ephemeral: true }); - } - }, -}; -function formatKeys(keys) { - let string = ""; - for (const item of keys) { - if (string.length !== 0) - string += "======"; - string += ` - **User**: <@${item.id}> - **Key**: \`${item.key}\` - **Request Count**: \`${item.requestCount}\` - **Created At**: \`${item.createdAt}\` - **Updated At**: \`${item.updatedAt}\` - `; - } - return string; -} diff --git a/anify-manager/dist/bot/commands/ping.d.ts b/anify-manager/dist/bot/commands/ping.d.ts deleted file mode 100644 index d353b6e..0000000 --- a/anify-manager/dist/bot/commands/ping.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CommandInteraction, SlashCommandBuilder } from "discord.js"; -declare const _default: { - data: SlashCommandBuilder; - execute(interaction: CommandInteraction): Promise; -}; -export default _default; diff --git a/anify-manager/dist/bot/commands/ping.js b/anify-manager/dist/bot/commands/ping.js deleted file mode 100644 index 4705de6..0000000 --- a/anify-manager/dist/bot/commands/ping.js +++ /dev/null @@ -1,9 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const discord_js_1 = require("discord.js"); -exports.default = { - data: new discord_js_1.SlashCommandBuilder().setName("ping").setDescription("Replies with Pong!"), - async execute(interaction) { - await interaction.reply("Pong!"); - }, -}; diff --git a/anify-manager/dist/bot/commands/site.d.ts b/anify-manager/dist/bot/commands/site.d.ts deleted file mode 100644 index d353b6e..0000000 --- a/anify-manager/dist/bot/commands/site.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CommandInteraction, SlashCommandBuilder } from "discord.js"; -declare const _default: { - data: SlashCommandBuilder; - execute(interaction: CommandInteraction): Promise; -}; -export default _default; diff --git a/anify-manager/dist/bot/commands/site.js b/anify-manager/dist/bot/commands/site.js deleted file mode 100644 index c5406ad..0000000 --- a/anify-manager/dist/bot/commands/site.js +++ /dev/null @@ -1,19 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const colors_json_1 = __importDefault(require("../colors.json")); -const discord_js_1 = require("discord.js"); -const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setTitle("Anify") - .setDescription("Read an extensive library of manga and light novels or watch anime ad-free with customizable subtitles!\nhttps://anify.tv/") - .setURL("https://anify.tv/") - .setTimestamp(); -exports.default = { - data: new discord_js_1.SlashCommandBuilder().setName("site").setDescription("Link to the Anify website."), - async execute(interaction) { - await interaction.reply({ embeds: [embed] }); - }, -}; diff --git a/anify-manager/dist/bot/commands/stats.d.ts b/anify-manager/dist/bot/commands/stats.d.ts deleted file mode 100644 index d353b6e..0000000 --- a/anify-manager/dist/bot/commands/stats.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CommandInteraction, SlashCommandBuilder } from "discord.js"; -declare const _default: { - data: SlashCommandBuilder; - execute(interaction: CommandInteraction): Promise; -}; -export default _default; diff --git a/anify-manager/dist/bot/commands/stats.js b/anify-manager/dist/bot/commands/stats.js deleted file mode 100644 index 4bd1c74..0000000 --- a/anify-manager/dist/bot/commands/stats.js +++ /dev/null @@ -1,102 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const colors_json_1 = __importDefault(require("../colors.json")); -const discord_js_1 = require("discord.js"); -const axios_1 = __importDefault(require("axios")); -const manager_1 = require("../../manager"); -const __1 = require(".."); -let embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setDescription("Loading...") - .setTimestamp(); -async function getStats() { - const start = new Date(Date.now()); - const apiStats = (await (0, axios_1.default)(`${__1.api}/stats?apikey=${__1.masterKey}`)).data; - const end = new Date(Date.now()); - const apiTime = end.getTime() - start.getTime(); - const start1 = new Date(Date.now()); - (await (0, axios_1.default)(`${__1.auth}/`)).data; - const end1 = new Date(Date.now()); - const authTime = end1.getTime() - start1.getTime(); - const start2 = new Date(Date.now()); - (await (0, axios_1.default)(`${__1.frontend}/`)).data; - const end2 = new Date(Date.now()); - const frontendTime = end2.getTime() - start2.getTime(); - const info = await (0, manager_1.list)(); - let infoString = ""; - for (let i = 0; i < info.length; i++) { - const proc = info[i]; - const pid = proc.pid; - const name = proc.name; - const upTime = new Date(proc.pm2_env.pm_uptime); // 1683653849001 - const createdAt = new Date(proc.pm2_env.created_at); // 1683653849001 - const restartTime = proc.pm2_env.restart_time; // 0 - const memory = proc.monit.memory; // 150683648 - const memoryInMb = memory / (1024 * 1024); - const memoryFormatted = memoryInMb < 1024 ? `${memoryInMb.toFixed(2)}mb` : `${(memoryInMb / 1024).toFixed(2)}GB`; - const cpu = proc.monit.cpu; // 0 - infoString += ` - \`\`\`${name}\`\`\` - **PID**: \`${pid}\` - **Uptime**: \`${formatDate(upTime)}\` - **Started At**: \`${`${createdAt.getMonth() + 1}/${createdAt.getDate()}/${createdAt.getFullYear()} - ${createdAt.getHours()}:${createdAt.getMinutes()} ${createdAt.getHours() >= 12 ? "PM" : "AM"}`}\` - **Restarts**: \`${restartTime}\` - **Memory Usage**: \`${memoryFormatted}\` - **CPU Usage**: \`${cpu}%\` - `; - } - const anime = apiStats.anime; - const manga = apiStats.manga; - const novels = apiStats.novels; - embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setTitle("Anify - Stats") - .setDescription(` - \`\`\`Media Count\`\`\` - **Anime**: \`${anime}\` - **Manga**: \`${manga}\` - **Novels**: \`${novels}\` - - \`\`\`Processes\`\`\` - **API Response**: \`${apiTime}ms\` - **Frontend Response**: \`${frontendTime}ms\` - **Auth Response**: \`${authTime}ms\` - ${infoString} - `) - .setTimestamp(); -} -function formatDate(date) { - const seconds = Math.floor((new Date().getTime() - date.getTime()) / 1000); - let interval = Math.floor(seconds / 31536000); - if (interval >= 1) { - return interval + " years ago"; - } - interval = Math.floor(seconds / 2592000); - if (interval >= 1) { - return interval + " months ago"; - } - interval = Math.floor(seconds / 86400); - if (interval >= 1) { - return interval + " days ago"; - } - interval = Math.floor(seconds / 3600); - if (interval >= 1) { - return interval + " hours ago"; - } - interval = Math.floor(seconds / 60); - if (interval >= 1) { - return interval + " minutes ago"; - } - return Math.floor(seconds) + " seconds ago"; -} -exports.default = { - data: new discord_js_1.SlashCommandBuilder().setName("stats").setDescription("Get stats about the website."), - async execute(interaction) { - await interaction.reply({ embeds: [embed] }); - await getStats(); - await interaction.editReply({ embeds: [embed] }); - }, -}; diff --git a/anify-manager/dist/bot/commands/unassign.d.ts b/anify-manager/dist/bot/commands/unassign.d.ts deleted file mode 100644 index 1ae382f..0000000 --- a/anify-manager/dist/bot/commands/unassign.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CommandInteraction, SlashCommandBuilder } from "discord.js"; -declare const _default: { - data: Omit; - execute(interaction: CommandInteraction): Promise | undefined>; -}; -export default _default; diff --git a/anify-manager/dist/bot/commands/unassign.js b/anify-manager/dist/bot/commands/unassign.js deleted file mode 100644 index 3c3fc34..0000000 --- a/anify-manager/dist/bot/commands/unassign.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const colors_json_1 = __importDefault(require("../colors.json")); -const discord_js_1 = require("discord.js"); -const axios_1 = __importDefault(require("axios")); -const __1 = require(".."); -exports.default = { - data: new discord_js_1.SlashCommandBuilder() - .setName("unassign") - .setDescription("Unassigns an API key to an user.") - .addStringOption((option) => option.setName("master-key").setDescription("Master key").setRequired(true)) - .addStringOption((option) => option.setName("key").setDescription("The key to assign").setRequired(true)), - async execute(interaction) { - const master = interaction.options.get("master-key")?.value; - const key = interaction.options.get("key")?.value; - if (master != __1.masterKey) { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription("You don't have permission to run this command!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - try { - const { data } = await axios_1.default.get(`${__1.api}/unassign?key=${key}&apikey=${master}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - if (data.error) { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription(JSON.stringify(data)) - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.success) - .setDescription(`Successfully unassigned key \`${key}\`!`) - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - } - catch (e) { - await interaction.reply("Error."); - } - }, -}; diff --git a/anify-manager/dist/bot/commands/updateKeys.d.ts b/anify-manager/dist/bot/commands/updateKeys.d.ts deleted file mode 100644 index 1ae382f..0000000 --- a/anify-manager/dist/bot/commands/updateKeys.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CommandInteraction, SlashCommandBuilder } from "discord.js"; -declare const _default: { - data: Omit; - execute(interaction: CommandInteraction): Promise | undefined>; -}; -export default _default; diff --git a/anify-manager/dist/bot/commands/updateKeys.js b/anify-manager/dist/bot/commands/updateKeys.js deleted file mode 100644 index d972c3e..0000000 --- a/anify-manager/dist/bot/commands/updateKeys.js +++ /dev/null @@ -1,45 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const colors_json_1 = __importDefault(require("../colors.json")); -const discord_js_1 = require("discord.js"); -const axios_1 = __importDefault(require("axios")); -const __1 = require(".."); -exports.default = { - data: new discord_js_1.SlashCommandBuilder() - .setName("update") - .setDescription("Updates API keys.") - .addStringOption((option) => option.setName("key").setDescription("Master key").setRequired(true)), - async execute(interaction) { - const key = interaction.options.get("key")?.value; - if (key != __1.masterKey) { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription("You don't have permission to run this command!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - try { - const { data } = await axios_1.default.get(`${__1.api}/update-keys?apikey=${key}`); - if (data.success === "true") { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setDescription("Success!") - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - } - else { - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setDescription("Error updating keys." + "\n" + data) - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - } - } - catch (e) { - await interaction.reply("Error."); - } - }, -}; diff --git a/anify-manager/dist/bot/events/buttons.d.ts b/anify-manager/dist/bot/events/buttons.d.ts deleted file mode 100644 index 5a93f18..0000000 --- a/anify-manager/dist/bot/events/buttons.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const _default: import("discord.js").Client; -export default _default; diff --git a/anify-manager/dist/bot/events/buttons.js b/anify-manager/dist/bot/events/buttons.js deleted file mode 100644 index 928de5f..0000000 --- a/anify-manager/dist/bot/events/buttons.js +++ /dev/null @@ -1,159 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const discord_js_1 = require("discord.js"); -const __1 = require(".."); -const roles_json_1 = __importDefault(require("../roles.json")); -const colors_json_1 = __importDefault(require("../colors.json")); -const axios_1 = __importDefault(require("axios")); -const __2 = require(".."); -const manager_1 = require("../../manager"); -exports.default = __1.client.on(discord_js_1.Events.InteractionCreate, async (interaction) => { - if (interaction.isButton()) { - if (interaction.customId === "development-ping") { - await interaction.deferReply({ ephemeral: true }); - const hasRole = await toggleRole(interaction.guild, interaction.member, roles_json_1.default.development_ping); - if (hasRole === null) { - const pingEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription("<@&" + roles_json_1.default.development_ping + "> role doesn't exist. Please contact a staff member.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - return; - } - if (!hasRole) { - const pingEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.success) - .setDescription("Gave you the <@&" + roles_json_1.default.development_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } - else { - const pingEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.denied) - .setDescription("Removed the <@&" + roles_json_1.default.development_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } - } - if (interaction.customId === "scanlation-ping") { - await interaction.deferReply({ ephemeral: true }); - const hasRole = await toggleRole(interaction.guild, interaction.member, roles_json_1.default.scanlation_ping); - if (hasRole === null) { - const pingEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription("<@&" + roles_json_1.default.scanlation_ping + "> role doesn't exist. Please contact a staff member.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - return; - } - if (!hasRole) { - const pingEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.success) - .setDescription("Gave you the <@&" + roles_json_1.default.scanlation_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } - else { - const pingEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.denied) - .setDescription("Removed the <@&" + roles_json_1.default.scanlation_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } - } - if (interaction.customId === "announcement-ping") { - await interaction.deferReply({ ephemeral: true }); - const hasRole = await toggleRole(interaction.guild, interaction.member, roles_json_1.default.announcement_ping); - if (hasRole === null) { - const pingEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription("<@&" + roles_json_1.default.announcement_ping + "> role doesn't exist. Please contact a staff member.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - return; - } - if (!hasRole) { - const pingEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.success) - .setDescription("Gave you the <@&" + roles_json_1.default.announcement_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } - else { - const pingEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.denied) - .setDescription("Removed the <@&" + roles_json_1.default.announcement_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } - } - if (interaction.customId.includes("suggest")) { - await interaction.deferReply({ ephemeral: true }); - const time = 600000; - let timeTill = Date.now() / 1000; - timeTill += parseInt(String(time / 1000)); - const suggestEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.success) - .setDescription("Make your suggestion now! You have until to make your suggestion.") - .setTimestamp(); - await interaction.editReply({ embeds: [suggestEmbed] }); - interaction.channel.permissionOverwrites.edit(interaction.member.id, { SendMessages: true }); - setTimeout(() => { - interaction.channel.permissionOverwrites.edit(interaction.member.id, { SendMessages: false }); - }, time); - } - if (interaction.customId.includes("getkey")) { - await interaction.deferReply({ ephemeral: true }); - const { data } = await axios_1.default.get(`${__2.api}/key?id=${interaction.member?.user.id}&apikey=${__2.masterKey}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - if (data.error) { - // Generate key - const key = await (0, manager_1.generateKey)(); - const { data } = await axios_1.default.get(`${__2.api}/assign?id=${interaction.member?.user.id}&key=${key}&apikey=${__2.masterKey}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - if (data.error) { - // Return error - const errorEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription(`An error has occurred! Please contact a staff member. Error: \`${data.error}\``) - .setTimestamp(); - await interaction.editReply({ embeds: [errorEmbed] }); - return; - } - const keyEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.success) - .setDescription(`Your key is \`${key}\`! You can run **/get** to display your current key.`) - .setTimestamp(); - await interaction.editReply({ embeds: [keyEmbed] }); - return; - } - const embed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.error) - .setDescription(`You already have a key! Key: \`${data.key}\``) - .setTimestamp(); - await interaction.editReply({ embeds: [embed] }); - } - } -}); -async function toggleRole(guild, member, id) { - return new Promise(async function (resolve, reject) { - const role = guild.roles.cache.get(id); - if (!role) { - resolve(null); - return; - } - if (!member.roles.cache.has(role.id)) { - member.roles.add(role); - resolve(false); - } - else { - member.roles.remove(role); - resolve(true); - } - }); -} diff --git a/anify-manager/dist/bot/events/guildMemberAdd.d.ts b/anify-manager/dist/bot/events/guildMemberAdd.d.ts deleted file mode 100644 index 5a93f18..0000000 --- a/anify-manager/dist/bot/events/guildMemberAdd.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const _default: import("discord.js").Client; -export default _default; diff --git a/anify-manager/dist/bot/events/guildMemberAdd.js b/anify-manager/dist/bot/events/guildMemberAdd.js deleted file mode 100644 index e89ca7e..0000000 --- a/anify-manager/dist/bot/events/guildMemberAdd.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const discord_js_1 = require("discord.js"); -const __1 = require(".."); -const roles_json_1 = __importDefault(require("../roles.json")); -exports.default = __1.client.on(discord_js_1.Events.GuildMemberAdd, async (member) => { - const role = member.guild.roles.cache.find((role) => role.id === roles_json_1.default.guest); - if (!role) { - return; - } - member.roles.add(role); - console.log(member.user.tag + " joined the server.".dim); -}); diff --git a/anify-manager/dist/bot/events/guildMemberRemove.d.ts b/anify-manager/dist/bot/events/guildMemberRemove.d.ts deleted file mode 100644 index 5a93f18..0000000 --- a/anify-manager/dist/bot/events/guildMemberRemove.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const _default: import("discord.js").Client; -export default _default; diff --git a/anify-manager/dist/bot/events/guildMemberRemove.js b/anify-manager/dist/bot/events/guildMemberRemove.js deleted file mode 100644 index c2e60ac..0000000 --- a/anify-manager/dist/bot/events/guildMemberRemove.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const discord_js_1 = require("discord.js"); -const __1 = require(".."); -exports.default = __1.client.on(discord_js_1.Events.GuildMemberRemove, async (member) => { - console.log(member.user.tag + " left the server.".dim); -}); diff --git a/anify-manager/dist/bot/events/interactionCreate.d.ts b/anify-manager/dist/bot/events/interactionCreate.d.ts deleted file mode 100644 index 5a93f18..0000000 --- a/anify-manager/dist/bot/events/interactionCreate.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const _default: import("discord.js").Client; -export default _default; diff --git a/anify-manager/dist/bot/events/interactionCreate.js b/anify-manager/dist/bot/events/interactionCreate.js deleted file mode 100644 index de349df..0000000 --- a/anify-manager/dist/bot/events/interactionCreate.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const discord_js_1 = require("discord.js"); -const __1 = require(".."); -const colors_1 = __importDefault(require("colors")); -exports.default = __1.client.on(discord_js_1.Events.InteractionCreate, async (interaction) => { - if (!interaction.isChatInputCommand()) - return; - const command = interaction.client.commands.get(interaction.commandName); - if (!command) { - console.error(colors_1.default.red(`No command matching ${interaction.commandName} was found.`)); - return; - } - try { - await command.execute(interaction); - } - catch (error) { - console.error(colors_1.default.red(`Error executing ${interaction.commandName}`)); - console.error(error); - } -}); diff --git a/anify-manager/dist/bot/events/messageCreate.d.ts b/anify-manager/dist/bot/events/messageCreate.d.ts deleted file mode 100644 index 5a93f18..0000000 --- a/anify-manager/dist/bot/events/messageCreate.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const _default: import("discord.js").Client; -export default _default; diff --git a/anify-manager/dist/bot/events/messageCreate.js b/anify-manager/dist/bot/events/messageCreate.js deleted file mode 100644 index eeef63d..0000000 --- a/anify-manager/dist/bot/events/messageCreate.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const discord_js_1 = require("discord.js"); -const __1 = require(".."); -const channels_json_1 = __importDefault(require("../channels.json")); -const colors_json_1 = __importDefault(require("../colors.json")); -let suggestion = []; -const botId = process.env.CLIENT ?? ""; -exports.default = __1.client.on(discord_js_1.Events.MessageCreate, async (message) => { - if (message.channel.id === channels_json_1.default.suggestions && message.member?.id != botId) { - const messageDelete = message.channel.messages.cache.get(suggestion[suggestion.length - 1]); - suggestion = []; - const avatarUrl = message.author.id && message.author.avatar ? `https://cdn.discordapp.com/avatars/${message.author.id}/${message.author.avatar}.png` : "https://i.waifu.pics/1y5O6HN.jpg"; - const suggestEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setTitle("Suggestion By " + message.member?.user.tag) - .setDescription(message.content) - .setFooter({ text: message.member?.user.tag ?? "", iconURL: avatarUrl }) - .setTimestamp(); - const makeSuggestEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setTitle("Make a Suggestion") - .setDescription("You will have **10 minutes** to finish making your suggestion before the channel will lock for you. Please also make sure your suggestion has not been made before. Troll suggestions will get deleted!") - .setFooter({ text: "Anify#7768", iconURL: "https://i.waifu.pics/1y5O6HN.jpg" }) - .setTimestamp(); - const suggestButton = new discord_js_1.ActionRowBuilder().addComponents(new discord_js_1.ButtonBuilder() - .setCustomId("suggestion-" + message.id) - .setLabel("Suggest Something") - .setStyle(discord_js_1.ButtonStyle.Success)); - if (messageDelete != undefined) { - messageDelete.delete(); - } - message.channel.send({ embeds: [suggestEmbed] }).then((msg) => { - message.channel.send({ embeds: [makeSuggestEmbed], components: [suggestButton] }).then((mssg) => { - suggestion.push(mssg.id); - }); - message.delete(); - message.channel.messages.fetch(msg.id).then((mssg) => { - if (!mssg) { - return; - } - mssg.react("👍"); - mssg.react("👎"); - }); - message.channel.permissionOverwrites.edit(message.member?.id, { SendMessages: false }); - }); - } -}); diff --git a/anify-manager/dist/bot/events/ready.d.ts b/anify-manager/dist/bot/events/ready.d.ts deleted file mode 100644 index 5a93f18..0000000 --- a/anify-manager/dist/bot/events/ready.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const _default: import("discord.js").Client; -export default _default; diff --git a/anify-manager/dist/bot/events/ready.js b/anify-manager/dist/bot/events/ready.js deleted file mode 100644 index 641708b..0000000 --- a/anify-manager/dist/bot/events/ready.js +++ /dev/null @@ -1,11 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const discord_js_1 = require("discord.js"); -const __1 = require(".."); -const colors_1 = __importDefault(require("colors")); -exports.default = __1.client.once(discord_js_1.Events.ClientReady, (c) => { - console.log(colors_1.default.green(`Ready! Logged in as ${c.user.tag}`)); -}); diff --git a/anify-manager/dist/bot/events/status.d.ts b/anify-manager/dist/bot/events/status.d.ts deleted file mode 100644 index 35a35db..0000000 --- a/anify-manager/dist/bot/events/status.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const _default: Promise; -export default _default; diff --git a/anify-manager/dist/bot/events/status.js b/anify-manager/dist/bot/events/status.js deleted file mode 100644 index 3cfbbcb..0000000 --- a/anify-manager/dist/bot/events/status.js +++ /dev/null @@ -1,78 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const discord_js_1 = require("discord.js"); -const __1 = require(".."); -const colors_json_1 = __importDefault(require("../colors.json")); -const channels_json_1 = __importDefault(require("../channels.json")); -const axios_1 = __importDefault(require("axios")); -const frontend = process.env.FRONTEND ?? ""; -const api = process.env.API ?? ""; -const auth = process.env.AUTH ?? ""; -const updateStatusEmbed = async () => { - const channelId = channels_json_1.default.status; // Replace with your channel ID - const channel = await __1.client.channels.fetch(channelId); - const req1 = await (0, axios_1.default)(frontend).catch((err) => { - return null; - }); - const req2 = await (0, axios_1.default)(api).catch((err) => { - return null; - }); - const req3 = await (0, axios_1.default)(auth).catch((err) => { - return null; - }); - const statusEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setTitle("Status") - .setDescription(`**Frontend**: ${req1 ? "✅" : "❌"}\n**Backend**: ${req2 ? "✅" : "❌"}\n**Authentication**: ${req3 ? "✅" : "❌"}`); - if (!channel) { - console.error("Channel not found."); - return; - } - if (channel instanceof discord_js_1.TextChannel) { - const messages = await channel.messages.fetch(); - const lastMessage = messages.first(); - if (lastMessage && lastMessage.author.id === __1.client.user?.id) { - await lastMessage.edit({ embeds: [statusEmbed] }); - } - else { - await channel.send({ embeds: [statusEmbed] }); - } - } -}; -const createKeyButtons = async () => { - const channelId = channels_json_1.default.api; // Replace with your channel ID - const channel = await __1.client.channels.fetch(channelId); - const keyEmbed = new discord_js_1.EmbedBuilder() - .setColor(colors_json_1.default.neutral) - .setTitle("Get API Key") - .setDescription("Get your own API key for development! API documentation can be viewed [here](https://docs.anify.tv). Only one API key can be generated per user. Abusing this system will result in a permanent ban from the API."); - const keyButton = new discord_js_1.ActionRowBuilder().addComponents(new discord_js_1.ButtonBuilder().setCustomId("getkey").setLabel("Get Key").setStyle(discord_js_1.ButtonStyle.Primary)); - if (!channel) { - console.error("Channel not found."); - return; - } - if (channel instanceof discord_js_1.TextChannel) { - const messages = await channel.messages.fetch(); - const lastMessage = messages.first(); - if (lastMessage && lastMessage.author.id === __1.client.user?.id) { - return; - } - else { - await channel.send({ embeds: [keyEmbed], components: [keyButton] }); - } - } -}; -async function runStatusEmbed() { - setTimeout(async () => { - await updateStatusEmbed(); - await createKeyButtons(); - setInterval(() => { - updateStatusEmbed(); - createKeyButtons(); - }, 300000); - }, 10000); -} -exports.default = runStatusEmbed(); diff --git a/anify-manager/dist/bot/index.d.ts b/anify-manager/dist/bot/index.d.ts deleted file mode 100644 index 4179358..0000000 --- a/anify-manager/dist/bot/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Client } from "discord.js"; -export declare const masterKey: string; -export declare const api: string; -export declare const auth: string; -export declare const frontend: string; -export declare const client: Client; -export declare function registerCommands(): Promise; -export declare function loadCommands(): Promise; -export declare function loadEvents(): Promise; -export declare function login(): Promise; diff --git a/anify-manager/dist/bot/index.js b/anify-manager/dist/bot/index.js deleted file mode 100644 index c9b9baf..0000000 --- a/anify-manager/dist/bot/index.js +++ /dev/null @@ -1,127 +0,0 @@ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -var _a, _b, _c; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.login = exports.loadEvents = exports.loadCommands = exports.registerCommands = exports.client = exports.frontend = exports.auth = exports.api = exports.masterKey = void 0; -// Require the necessary discord.js classes -const discord_js_1 = require("discord.js"); -const colors_1 = __importDefault(require("colors")); -const fs_1 = require("fs"); -const path_1 = require("path"); -const token = process.env.TOKEN ?? ""; -const clientId = process.env.CLIENT ?? ""; -const guildId = process.env.GUILD ?? ""; -exports.masterKey = process.env.MASTER_KEY ?? ""; -exports.api = process.env.API ?? ""; -exports.auth = process.env.AUTH ?? ""; -exports.frontend = process.env.FRONTEND ?? ""; -exports.client = new discord_js_1.Client({ - shards: "auto", - allowedMentions: { - parse: [], - repliedUser: true, - }, - intents: [discord_js_1.GatewayIntentBits.GuildMembers, discord_js_1.GatewayIntentBits.Guilds, discord_js_1.GatewayIntentBits.GuildMessages, discord_js_1.GatewayIntentBits.GuildVoiceStates, discord_js_1.GatewayIntentBits.GuildMessageReactions, discord_js_1.GatewayIntentBits.MessageContent], - presence: { - activities: [{ name: "Anime", type: discord_js_1.ActivityType.Watching }], - status: "online", - }, - partials: [discord_js_1.Partials.Message, discord_js_1.Partials.Channel, discord_js_1.Partials.Reaction, discord_js_1.Partials.GuildMember], -}); -async function registerCommands() { - const commands = []; - const rest = new discord_js_1.REST().setToken(token); - const existingCommands = await rest.get(discord_js_1.Routes.applicationGuildCommands(clientId, guildId)); - existingCommands.forEach((command) => { - commands.push(command); - console.log(colors_1.default.gray("Registered ") + colors_1.default.blue(`/${command.name}`) + colors_1.default.gray(".")); - }); - for (const file of (0, fs_1.readdirSync)((0, path_1.join)(__dirname, "./commands"))) { - const filePath = (0, path_1.join)((0, path_1.join)(__dirname, "./commands"), file); - const { default: command } = await (_a = filePath, Promise.resolve().then(() => __importStar(require(_a)))); - // Set a new item in the Collection with the key as the command name and the value as the exported module - if ("data" in command && "execute" in command) { - let canPush = true; - for (let i = 0; i < existingCommands.length; i++) { - if (command.data.name === existingCommands[i].name) { - console.log(colors_1.default.yellow(`[WARNING] The command at ${filePath} is already registered. Skipping...`)); - canPush = false; - break; - } - } - if (canPush) { - commands.push(command.data.toJSON()); - console.log(colors_1.default.gray("Registered ") + colors_1.default.blue(`/${command.data.name}`) + colors_1.default.gray(".")); - } - } - else { - console.log(colors_1.default.yellow(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`)); - } - } - // If there are new commands to register - if (commands.length > 0) { - try { - console.log(colors_1.default.yellow(`Started refreshing ${commands.length} application (/) commands.`)); - // The post method is used to create new commands without overwriting existing ones - const data = await rest.put(discord_js_1.Routes.applicationGuildCommands(clientId, guildId), { body: commands }); - console.log(colors_1.default.green(`Successfully registered ${data.length} new application (/) commands.`)); - } - catch (error) { - console.error(error); - } - } - else { - console.log(colors_1.default.gray("No new commands to register.")); - } -} -exports.registerCommands = registerCommands; -async function loadCommands() { - exports.client.commands = new discord_js_1.Collection(); - for (const file of (0, fs_1.readdirSync)((0, path_1.join)(__dirname, "./commands"))) { - const filePath = (0, path_1.join)((0, path_1.join)(__dirname, "./commands"), file); - const { default: command } = await (_b = filePath, Promise.resolve().then(() => __importStar(require(_b)))); - // Set a new item in the Collection with the key as the command name and the value as the exported module - if ("data" in command && "execute" in command) { - exports.client.commands.set(command.data.name, command); - console.log(colors_1.default.gray("Registered command ") + colors_1.default.blue(`/${command.data.name}`) + colors_1.default.gray(".")); - } - } -} -exports.loadCommands = loadCommands; -async function loadEvents() { - for (const file of (0, fs_1.readdirSync)((0, path_1.join)(__dirname, "./events"))) { - const filePath = (0, path_1.join)((0, path_1.join)(__dirname, "./events"), file); - await (_c = filePath, Promise.resolve().then(() => __importStar(require(_c)))); - console.log(colors_1.default.gray("Registered event ") + colors_1.default.blue(`${file}`) + colors_1.default.gray(".")); - } -} -exports.loadEvents = loadEvents; -async function login() { - await exports.client.login(token); -} -exports.login = login; diff --git a/anify-manager/dist/bot/roles.json b/anify-manager/dist/bot/roles.json deleted file mode 100644 index 1013fc7..0000000 --- a/anify-manager/dist/bot/roles.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "moderation": "950965073281708044", - "guest": "950964334983520257", - "muted": "952228969724383292", - "announcement_ping": "1040385046068068403", - "development_ping": "1040384998701797537", - "scanlation_ping": "1040385081094705252" -} diff --git a/anify-manager/dist/index.d.ts b/anify-manager/dist/index.d.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/anify-manager/dist/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/anify-manager/dist/index.js b/anify-manager/dist/index.js deleted file mode 100644 index c5ae573..0000000 --- a/anify-manager/dist/index.js +++ /dev/null @@ -1,70 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const dotenv_1 = __importDefault(require("dotenv")); -dotenv_1.default.config(); -const colors_1 = __importDefault(require("colors")); -const bot_1 = require("./bot"); -const manager_1 = require("./manager"); -(async function () { - try { - await Promise.all([startManager(), startBot()]); - } - catch (err) { - console.error(colors_1.default.red("Error: "), err); - } -})(); -async function startManager() { - await (0, manager_1.connect)(); - await Promise.all([(0, manager_1.start)("anify-frontend" /* Process.FRONTEND */), (0, manager_1.start)("anify-backend" /* Process.BACKEND */), (0, manager_1.start)("anify-auth" /* Process.AUTH */)]).catch((err) => { - console.error(colors_1.default.red("Error: "), err); - }); - console.log(colors_1.default.green("Started process manager.")); -} -async function startBot() { - if (!process.env.TOKEN) { - console.log(colors_1.default.red("No Discord token provided. Discord bot will not be started up.")); - return; - } - if (!process.env.CLIENT) { - console.log(colors_1.default.red("No Discord client ID provided. Discord bot will not be started up.")); - return; - } - if (!process.env.GUILD) { - console.log(colors_1.default.red("No Discord guild ID provided. Discord bot will not be started up.")); - return; - } - if (!process.env.FRONTEND) { - console.log(colors_1.default.yellow("WARNING: Frontend URL not provided. Discord bot will likely have issues. Please provide the URL in the .env file.")); - } - if (!process.env.API) { - console.log(colors_1.default.yellow("WARNING: API URL not provided. Discord bot will likely have issues. Please provide the URL in the .env file.")); - } - if (!process.env.AUTH) { - console.log(colors_1.default.yellow("WARNING: Auth URL not provided. Discord bot will likely have issues. Please provide the URL in the .env file.")); - } - if (!process.env.MASTER_KEY) { - console.log(colors_1.default.yellow("WARNING: Master key not provided. Discord bot will likely have issues. Please provide the key in the .env file.")); - } - await Promise.all([(0, bot_1.registerCommands)(), (0, bot_1.loadCommands)(), (0, bot_1.loadEvents)(), (0, bot_1.login)()]).catch((err) => { - console.error(colors_1.default.red("Error: "), err); - }); -} -process.on("beforeExit", async () => { - console.log(colors_1.default.red("Stopping services...")); - await Promise.all([(0, manager_1.remove)("anify-frontend" /* Process.FRONTEND */), (0, manager_1.remove)("anify-backend" /* Process.BACKEND */), (0, manager_1.remove)("anify-auth" /* Process.AUTH */)]).catch((err) => { - console.error(colors_1.default.red("Error: "), err); - }); -}); -process.on("unhandledRejection", (err) => { - console.error(colors_1.default.red("Unhandled Promise rejection: "), err); -}); -process.on("SIGINT", async () => { - console.log(colors_1.default.red("Stopping services...")); - await Promise.all([(0, manager_1.remove)("anify-frontend" /* Process.FRONTEND */), (0, manager_1.remove)("anify-backend" /* Process.BACKEND */)]).catch((err) => { - console.error(colors_1.default.red("Error: "), err); - }); - process.exit(); -}); diff --git a/anify-manager/dist/manager/index.d.ts b/anify-manager/dist/manager/index.d.ts deleted file mode 100644 index a0ea4ce..0000000 --- a/anify-manager/dist/manager/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -export declare function connect(): Promise; -export declare function list(): Promise; -export declare function start(process: Process): Promise; -export declare function reload(process: Process): Promise; -export declare function remove(process: Process): Promise; -export declare function stop(process: Process): Promise; -export declare function generateKey(): Promise; -export declare const enum Process { - FRONTEND = "anify-frontend", - BACKEND = "anify-backend", - AUTH = "anify-auth" -} diff --git a/anify-manager/dist/manager/index.js b/anify-manager/dist/manager/index.js deleted file mode 100644 index f424b6f..0000000 --- a/anify-manager/dist/manager/index.js +++ /dev/null @@ -1,135 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.generateKey = exports.stop = exports.remove = exports.reload = exports.start = exports.list = exports.connect = void 0; -const pm2_1 = __importDefault(require("pm2")); -const colors_1 = __importDefault(require("colors")); -const child_process_1 = require("child_process"); -async function connect() { - return new Promise((resolve, reject) => { - pm2_1.default.connect(async (err) => { - if (err) { - console.error(err); - process.exit(2); - } - resolve(true); - }); - }); -} -exports.connect = connect; -async function list() { - return new Promise((resolve, reject) => { - pm2_1.default.list((err, list) => { - if (err) - return reject(err); - resolve(list); - }); - }); -} -exports.list = list; -async function start(process) { - if (process === "anify-frontend" /* Process.FRONTEND */) { - return new Promise((resolve, reject) => { - pm2_1.default.start({ - script: "cd ../anify-frontend && npm run start", - name: "anify-frontend", - }, (err, apps) => { - if (err) { - console.error(colors_1.default.red("Error starting up frontend.")); - console.error(err); - pm2_1.default.disconnect(); - reject(err); - return; - } - resolve(true); - }); - }); - } - else if (process === "anify-backend" /* Process.BACKEND */) { - return new Promise((resolve, reject) => { - pm2_1.default.start({ - script: "cd ../anify-backend && NODE_ENV=production npm run start", - name: "anify-backend", - }, (err, apps) => { - if (err) { - console.error(colors_1.default.red("Error starting up backend.")); - console.error(err); - pm2_1.default.disconnect(); - reject(err); - return; - } - resolve(true); - }); - }); - } - else if (process === "anify-auth" /* Process.AUTH */) { - return new Promise((resolve, reject) => { - pm2_1.default.start({ - script: "cd ../anify-auth && npm run start", - name: "anify-auth", - }, (err, apps) => { - if (err) { - console.error(colors_1.default.red("Error starting up auth.")); - console.error(err); - pm2_1.default.disconnect(); - reject(err); - return; - } - resolve(true); - }); - }); - } -} -exports.start = start; -async function reload(process) { - return new Promise((resolve, reject) => { - pm2_1.default.reload(process, (err, proc) => { - if (err) - return reject(err); - resolve(true); - }); - }); -} -exports.reload = reload; -async function remove(process) { - return new Promise((resolve, reject) => { - pm2_1.default.delete(process, (err, proc) => { - if (err) - return reject(err); - resolve(true); - }); - }); -} -exports.remove = remove; -async function stop(process) { - return new Promise((resolve, reject) => { - pm2_1.default.stop(process, (err, proc) => { - if (err) - return reject(err); - resolve(true); - }); - }); -} -exports.stop = stop; -async function generateKey() { - return new Promise((resolve, reject) => { - (0, child_process_1.exec)("cd ../anify-backend && npm run create:key", (error, stdout, stderr) => { - if (error) { - console.error(`Error executing command: ${error.message}`); - reject(error); - } - else if (stderr) { - console.error(`Command error: ${stderr}`); - reject(new Error(stderr)); - } - else { - const lines = stdout.trim().split("\n"); - const key = lines[lines.length - 1].trim(); - resolve(key); - } - }); - }); -} -exports.generateKey = generateKey; diff --git a/anify-manager/dist/scripts/startBot.d.ts b/anify-manager/dist/scripts/startBot.d.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/anify-manager/dist/scripts/startBot.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/anify-manager/dist/scripts/startBot.js b/anify-manager/dist/scripts/startBot.js deleted file mode 100644 index 5cff233..0000000 --- a/anify-manager/dist/scripts/startBot.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const dotenv_1 = __importDefault(require("dotenv")); -dotenv_1.default.config(); -const colors_1 = __importDefault(require("colors")); -const bot_1 = require("../bot"); -(async function () { - await Promise.all([(0, bot_1.registerCommands)(), (0, bot_1.loadCommands)(), (0, bot_1.loadEvents)(), (0, bot_1.login)()]).catch((err) => { - console.error(colors_1.default.red("Error: "), err); - }); -})(); diff --git a/anify-manager/dist/test.d.ts b/anify-manager/dist/test.d.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/anify-manager/dist/test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/anify-manager/dist/test.js b/anify-manager/dist/test.js deleted file mode 100644 index bf8f878..0000000 --- a/anify-manager/dist/test.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const manager_1 = require("./manager"); -(0, manager_1.getList)("anify-backend" /* Process.BACKEND */).then(console.log); diff --git a/anify-manager/package-lock.json b/anify-manager/package-lock.json deleted file mode 100644 index 95a3464..0000000 --- a/anify-manager/package-lock.json +++ /dev/null @@ -1,6029 +0,0 @@ -{ - "name": "anify-manager", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "anify-manager", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "axios": "^0.27.2", - "colors": "^1.4.0", - "crypto-js": "^4.1.1", - "discord.js": "^14.11.0", - "dotenv": "^16.0.3", - "pm2": "^5.3.0" - }, - "devDependencies": { - "@types/node": "^18.16.2", - "@typescript-eslint/eslint-plugin": "^5.59.2", - "prettier": "2.8.8", - "prisma": "^4.13.0", - "prisma-json-types-generator": "^2.3.1", - "rimraf": "^5.0.0", - "ts-node": "^10.9.1", - "tsconfig-paths": "^4.2.0", - "tscpaths": "^0.0.9", - "tslib": "^2.5.0", - "typescript": "^4.9.5" - } - }, - "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/@discordjs/builders": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.3.tgz", - "integrity": "sha512-CTCh8NqED3iecTNuiz49mwSsrc2iQb4d0MjMdmS/8pb69Y4IlzJ/DIy/p5GFlgOrFbNO2WzMHkWKQSiJ3VNXaw==", - "dependencies": { - "@discordjs/formatters": "^0.3.1", - "@discordjs/util": "^0.3.1", - "@sapphire/shapeshift": "^3.8.2", - "discord-api-types": "^0.37.41", - "fast-deep-equal": "^3.1.3", - "ts-mixer": "^6.0.3", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/@discordjs/collection": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.1.tgz", - "integrity": "sha512-aWEc9DCf3TMDe9iaJoOnO2+JVAjeRNuRxPZQA6GVvBf+Z3gqUuWYBy2NWh4+5CLYq5uoc3MOvUQ5H5m8CJBqOA==", - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/@discordjs/formatters": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.1.tgz", - "integrity": "sha512-M7X4IGiSeh4znwcRGcs+49B5tBkNDn4k5bmhxJDAUhRxRHTiFAOTVUNQ6yAKySu5jZTnCbSvTYHW3w0rAzV1MA==", - "dependencies": { - "discord-api-types": "^0.37.41" - }, - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/@discordjs/rest": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.7.1.tgz", - "integrity": "sha512-Ofa9UqT0U45G/eX86cURQnX7gzOJLG2oC28VhIk/G6IliYgQF7jFByBJEykPSHE4MxPhqCleYvmsrtfKh1nYmQ==", - "dependencies": { - "@discordjs/collection": "^1.5.1", - "@discordjs/util": "^0.3.0", - "@sapphire/async-queue": "^1.5.0", - "@sapphire/snowflake": "^3.4.2", - "discord-api-types": "^0.37.41", - "file-type": "^18.3.0", - "tslib": "^2.5.0", - "undici": "^5.22.0" - }, - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/@discordjs/util": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.3.1.tgz", - "integrity": "sha512-HxXKYKg7vohx2/OupUN/4Sd02Ev3PBJ5q0gtjdcvXb0ErCva8jNHWfe/v5sU3UKjIB/uxOhc+TDOnhqffj9pRA==", - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/@discordjs/ws": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-0.8.3.tgz", - "integrity": "sha512-hcYtppanjHecbdNyCKQNH2I4RP9UrphDgmRgLYrATEQF1oo4sYSve7ZmGsBEXSzH72MO2tBPdWSThunbxUVk0g==", - "dependencies": { - "@discordjs/collection": "^1.5.1", - "@discordjs/rest": "^1.7.1", - "@discordjs/util": "^0.3.1", - "@sapphire/async-queue": "^1.5.0", - "@types/ws": "^8.5.4", - "@vladfrangu/async_event_emitter": "^2.2.1", - "discord-api-types": "^0.37.41", - "tslib": "^2.5.0", - "ws": "^8.13.0" - }, - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/@discordjs/ws/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@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, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", - "dev": true, - "peer": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.2", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", - "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", - "dev": true, - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", - "dev": true, - "peer": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true, - "peer": true - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "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/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.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/@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "dependencies": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "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, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "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, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@opencensus/core": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz", - "integrity": "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q==", - "dependencies": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^5.5.0", - "shimmer": "^1.2.0", - "uuid": "^3.2.1" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/@opencensus/core/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@opencensus/propagation-b3": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz", - "integrity": "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A==", - "dependencies": { - "@opencensus/core": "^0.0.8", - "uuid": "^3.2.1" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/@opencensus/propagation-b3/node_modules/@opencensus/core": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz", - "integrity": "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ==", - "dependencies": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^5.5.0", - "shimmer": "^1.2.0", - "uuid": "^3.2.1" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/@opencensus/propagation-b3/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pm2/agent": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.1.tgz", - "integrity": "sha512-QKHMm6yexcvdDfcNE7PL9D6uEjoQPGRi+8dh+rc4Hwtbpsbh5IAvZbz3BVGjcd4HaX6pt2xGpOohG7/Y2L4QLw==", - "dependencies": { - "async": "~3.2.0", - "chalk": "~3.0.0", - "dayjs": "~1.8.24", - "debug": "~4.3.1", - "eventemitter2": "~5.0.1", - "fast-json-patch": "^3.0.0-1", - "fclone": "~1.0.11", - "nssocket": "0.6.0", - "pm2-axon": "~4.0.1", - "pm2-axon-rpc": "~0.7.0", - "proxy-agent": "~5.0.0", - "semver": "~7.2.0", - "ws": "~7.4.0" - } - }, - "node_modules/@pm2/agent/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@pm2/agent/node_modules/dayjs": { - "version": "1.8.36", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", - "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==" - }, - "node_modules/@pm2/agent/node_modules/semver": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.3.tgz", - "integrity": "sha512-utbW9Z7ZxVvwiIWkdOMLOR9G/NFXh2aRucghkVrEMJWuC++r3lCkBC3LwqBinyHzGMAJxY5tn6VakZGHObq5ig==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@pm2/io": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@pm2/io/-/io-5.0.0.tgz", - "integrity": "sha512-3rToDVJaRoob5Lq8+7Q2TZFruoEkdORxwzFpZaqF4bmH6Bkd7kAbdPrI/z8X6k1Meq5rTtScM7MmDgppH6aLlw==", - "dependencies": { - "@opencensus/core": "0.0.9", - "@opencensus/propagation-b3": "0.0.8", - "async": "~2.6.1", - "debug": "~4.3.1", - "eventemitter2": "^6.3.1", - "require-in-the-middle": "^5.0.0", - "semver": "6.3.0", - "shimmer": "^1.2.0", - "signal-exit": "^3.0.3", - "tslib": "1.9.3" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/@pm2/io/node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/@pm2/io/node_modules/eventemitter2": { - "version": "6.4.9", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" - }, - "node_modules/@pm2/io/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@pm2/io/node_modules/tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" - }, - "node_modules/@pm2/js-api": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz", - "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==", - "dependencies": { - "async": "^2.6.3", - "axios": "^0.21.0", - "debug": "~4.3.1", - "eventemitter2": "^6.3.1", - "ws": "^7.0.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@pm2/js-api/node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/@pm2/js-api/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@pm2/js-api/node_modules/eventemitter2": { - "version": "6.4.9", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" - }, - "node_modules/@pm2/pm2-version-check": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", - "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==", - "dependencies": { - "debug": "^4.3.1" - } - }, - "node_modules/@prisma/debug": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-4.14.0.tgz", - "integrity": "sha512-K3yFVN3BZRCoSwit0uFAXSFlt3lz6iKJqPPZMuEH6n7zCFRBoQJhDT+QiMIfMdf6eOy4f0H4yK0KFRnx4TJA7Q==", - "dev": true, - "dependencies": { - "@types/debug": "4.1.7", - "debug": "4.3.4", - "strip-ansi": "6.0.1" - } - }, - "node_modules/@prisma/engines": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.14.0.tgz", - "integrity": "sha512-PDNlhP/1vyTgmNyiucGqGCdXIp7HIkkvKO50si3y3PcceeHvqtiKPaH1iJdz63jCWMVMbj2MElSxXPOeBvEVIQ==", - "dev": true, - "hasInstallScript": true - }, - "node_modules/@prisma/generator-helper": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.14.0.tgz", - "integrity": "sha512-cOULdYfbjxPqdN/ctHKYwqyjcOWaHxS4TuhvK9nCLFAgLh92VAla65aMgbmcqaynh1X6HVlGu0hLbHNACOqKRA==", - "dev": true, - "dependencies": { - "@prisma/debug": "4.14.0", - "@types/cross-spawn": "6.0.2", - "cross-spawn": "7.0.3", - "kleur": "4.1.5" - } - }, - "node_modules/@sapphire/async-queue": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", - "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==", - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@sapphire/shapeshift": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.8.2.tgz", - "integrity": "sha512-NXpnJAsxN3/h9TqQPntOeVWZrpIuucqXI3IWF6tj2fWCoRLCuVK5wx7Dtg7pRrtkYfsMUbDqgKoX26vrC5iYfA==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "lodash": "^4.17.21" - }, - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@sapphire/snowflake": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.4.2.tgz", - "integrity": "sha512-KJwlv5gkGjs1uFV7/xx81n3tqgBwBJvH94n1xDyH3q+JSmtsMeSleJffarEBfG2yAFeJiFA4BnGOK6FFPHc19g==", - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "engines": { - "node": ">= 6" - } - }, - "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.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "node_modules/@types/cross-spawn": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", - "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", - "dev": true, - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, - "node_modules/@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.16.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.6.tgz", - "integrity": "sha512-N7KINmeB8IN3vRR8dhgHEp+YpWvGFcpDoh5XZ8jB5a00AdFKCKEyyGTOPTddUf4JqU1ZKTVxkOxakDvchNVI2Q==" - }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true - }, - "node_modules/@types/ws": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", - "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz", - "integrity": "sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/type-utils": "5.59.5", - "@typescript-eslint/utils": "5.59.5", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz", - "integrity": "sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/typescript-estree": "5.59.5", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", - "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz", - "integrity": "sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.5", - "@typescript-eslint/utils": "5.59.5", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", - "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", - "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.5.tgz", - "integrity": "sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/typescript-estree": "5.59.5", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", - "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.5", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@vladfrangu/async_event_emitter": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.1.tgz", - "integrity": "sha512-XtUEAS0m6uVddXW+EImGunLiJZzWNWAZQBoQCUneowrYXPQ6y7c0iWEm/wVYyGpTixTIhUfLRSoYCwojL64htA==", - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peer": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "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, - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/amp": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", - "integrity": "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==" - }, - "node_modules/amp-message": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", - "integrity": "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==", - "dependencies": { - "amp": "0.3.1" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "engines": { - "node": ">=6" - } - }, - "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, - "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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "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==", - "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", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "peer": true - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "node_modules/async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "dependencies": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "engines": { - "node": "<=0.11.8 || >0.11.10" - } - }, - "node_modules/async-listener/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/blessed": { - "version": "0.1.81", - "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", - "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==", - "bin": { - "blessed": "bin/tput.js" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/bodec": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz", - "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==" - }, - "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": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true - }, - "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, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "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, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/charm": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", - "integrity": "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==" - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "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" - }, - "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==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cli-tableau": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz", - "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==", - "dependencies": { - "chalk": "3.0.0" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/cli-tableau/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "dependencies": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "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/croner": { - "version": "4.1.97", - "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz", - "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==" - }, - "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, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" - }, - "node_modules/culvert": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz", - "integrity": "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==" - }, - "node_modules/data-uri-to-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", - "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/dayjs": { - "version": "1.11.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", - "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "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==" - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/degenerator": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.4.tgz", - "integrity": "sha512-Z66uPeBfHZAHVmue3HPfyKu2Q0rC2cRxbTOsvmU/po5fvvcx27W4mIu9n0PUlQih4oUYvcG1BsbtVv8x7KDOSw==", - "dependencies": { - "ast-types": "^0.13.2", - "escodegen": "^1.8.1", - "esprima": "^4.0.0", - "vm2": "^3.9.17" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "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/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/discord-api-types": { - "version": "0.37.42", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.42.tgz", - "integrity": "sha512-1Huaj9cQ1W7/uryS8MZs/tZemnoKB94thM1cE40lep3rpU3q7WHqkdjN/veX0prTkYlPhcyLd/DeF/pBO8X8oQ==" - }, - "node_modules/discord.js": { - "version": "14.11.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.11.0.tgz", - "integrity": "sha512-CkueWYFQ28U38YPR8HgsBR/QT35oPpMbEsTNM30Fs8loBIhnA4s70AwQEoy6JvLcpWWJO7GY0y2BUzZmuBMepQ==", - "dependencies": { - "@discordjs/builders": "^1.6.3", - "@discordjs/collection": "^1.5.1", - "@discordjs/formatters": "^0.3.1", - "@discordjs/rest": "^1.7.1", - "@discordjs/util": "^0.3.1", - "@discordjs/ws": "^0.8.3", - "@sapphire/snowflake": "^3.4.2", - "@types/ws": "^8.5.4", - "discord-api-types": "^0.37.41", - "fast-deep-equal": "^3.1.3", - "lodash.snakecase": "^4.1.1", - "tslib": "^2.5.0", - "undici": "^5.22.0", - "ws": "^8.13.0" - }, - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/discord.js/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "dependencies": { - "shimmer": "^1.2.0" - } - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", - "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.40.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", - "dev": true, - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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, - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", - "dev": true, - "peer": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "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, - "peer": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/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, - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "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, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/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, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eventemitter2": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", - "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==" - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==" - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "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-patch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "peer": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fclone": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", - "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==" - }, - "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, - "peer": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-type": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.3.0.tgz", - "integrity": "sha512-pkPZ5OGIq0TYb37b8bHDLNeQSe1H2KlaQ2ySGpJkkr2KZdaWsO4QhPzHA0mQcsUW2cSqJk+4gM/UyLz/UFbXdQ==", - "dependencies": { - "readable-web-to-node-stream": "^3.0.2", - "strtok3": "^7.0.0", - "token-types": "^5.0.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" - } - }, - "node_modules/file-uri-to-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", - "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", - "engines": { - "node": ">= 6" - } - }, - "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==", - "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, - "peer": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "peer": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true, - "peer": true - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "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", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==", - "dependencies": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/get-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", - "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", - "dependencies": { - "@tootallnate/once": "1", - "data-uri-to-buffer": "3", - "debug": "4", - "file-uri-to-path": "2", - "fs-extra": "^8.1.0", - "ftp": "^0.3.10" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/git-node-fs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz", - "integrity": "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==" - }, - "node_modules/git-sha1": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz", - "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==" - }, - "node_modules/glob": { - "version": "7.2.3", - "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", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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, - "peer": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", - "dev": true - }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "peer": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "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/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "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, - "peer": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "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, - "peer": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "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/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-core-module": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", - "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "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-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "engines": { - "node": ">=0.12.0" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "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", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jackspeak": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", - "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/js-git": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", - "integrity": "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==", - "dependencies": { - "bodec": "^0.1.0", - "culvert": "^0.1.2", - "git-sha1": "^0.1.2", - "pako": "^0.2.5" - } - }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true, - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "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, - "peer": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "peer": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "peer": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "optional": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/lazy": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", - "integrity": "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==", - "engines": { - "node": ">=0.2.0" - } - }, - "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, - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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, - "peer": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "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, - "peer": true - }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" - }, - "node_modules/log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "engines": { - "node": ">=0.8.6" - } - }, - "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/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/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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", - "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", - "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" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" - }, - "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/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "peer": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "node_modules/needle": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", - "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "dependencies": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "bin": { - "needle": "bin/needle" - }, - "engines": { - "node": ">= 4.4.x" - } - }, - "node_modules/needle/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "engines": { - "node": ">= 0.4.0" - } - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nssocket": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz", - "integrity": "sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==", - "dependencies": { - "eventemitter2": "~0.4.14", - "lazy": "~1.0.11" - }, - "engines": { - "node": ">= 0.10.x" - } - }, - "node_modules/nssocket/node_modules/eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==" - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "peer": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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, - "peer": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "peer": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pac-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz", - "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4", - "get-uri": "3", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "5", - "pac-resolver": "^5.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "5" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/pac-resolver": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz", - "integrity": "sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==", - "dependencies": { - "degenerator": "^3.0.2", - "ip": "^1.1.5", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" - }, - "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, - "peer": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "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, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "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, - "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==" - }, - "node_modules/path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", - "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/peek-readable": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", - "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pidusage": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz", - "integrity": "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==", - "dependencies": { - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pm2": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.3.0.tgz", - "integrity": "sha512-xscmQiAAf6ArVmKhjKTeeN8+Td7ZKnuZFFPw1DGkdFPR/0Iyx+m+1+OpCdf9+HQopX3VPc9/wqPQHqVOfHum9w==", - "dependencies": { - "@pm2/agent": "~2.0.0", - "@pm2/io": "~5.0.0", - "@pm2/js-api": "~0.6.7", - "@pm2/pm2-version-check": "latest", - "async": "~3.2.0", - "blessed": "0.1.81", - "chalk": "3.0.0", - "chokidar": "^3.5.3", - "cli-tableau": "^2.0.0", - "commander": "2.15.1", - "croner": "~4.1.92", - "dayjs": "~1.11.5", - "debug": "^4.3.1", - "enquirer": "2.3.6", - "eventemitter2": "5.0.1", - "fclone": "1.0.11", - "mkdirp": "1.0.4", - "needle": "2.4.0", - "pidusage": "~3.0", - "pm2-axon": "~4.0.1", - "pm2-axon-rpc": "~0.7.1", - "pm2-deploy": "~1.0.2", - "pm2-multimeter": "^0.1.2", - "promptly": "^2", - "semver": "^7.2", - "source-map-support": "0.5.21", - "sprintf-js": "1.1.2", - "vizion": "~2.2.1", - "yamljs": "0.3.0" - }, - "bin": { - "pm2": "bin/pm2", - "pm2-dev": "bin/pm2-dev", - "pm2-docker": "bin/pm2-docker", - "pm2-runtime": "bin/pm2-runtime" - }, - "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "pm2-sysmonit": "^1.2.8" - } - }, - "node_modules/pm2-axon": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz", - "integrity": "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==", - "dependencies": { - "amp": "~0.3.1", - "amp-message": "~0.1.1", - "debug": "^4.3.1", - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=5" - } - }, - "node_modules/pm2-axon-rpc": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz", - "integrity": "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==", - "dependencies": { - "debug": "^4.3.1" - }, - "engines": { - "node": ">=5" - } - }, - "node_modules/pm2-deploy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz", - "integrity": "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==", - "dependencies": { - "run-series": "^1.1.8", - "tv4": "^1.3.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pm2-multimeter": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", - "integrity": "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==", - "dependencies": { - "charm": "~0.1.1" - } - }, - "node_modules/pm2-sysmonit": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz", - "integrity": "sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==", - "optional": true, - "dependencies": { - "async": "^3.2.0", - "debug": "^4.3.1", - "pidusage": "^2.0.21", - "systeminformation": "^5.7", - "tx2": "~1.0.4" - } - }, - "node_modules/pm2-sysmonit/node_modules/pidusage": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", - "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", - "optional": true, - "dependencies": { - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pm2/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "peer": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prisma": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.14.0.tgz", - "integrity": "sha512-+5dMl1uxMQb4RepndY6AwR9xi1cDcaGFICu+ws6/Nmgt93mFPNj8tYxSfTdmfg+rkNrUId9rk/Ac2vTgLe/oXA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@prisma/engines": "4.14.0" - }, - "bin": { - "prisma": "build/index.js", - "prisma2": "build/index.js" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/prisma-json-types-generator": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-2.4.0.tgz", - "integrity": "sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg==", - "dev": true, - "dependencies": { - "@prisma/generator-helper": "^4.10.1", - "tslib": "^2.5.0" - }, - "bin": { - "prisma-json-types-generator": "dist/bin.js" - }, - "engines": { - "node": ">=14.0" - }, - "funding": { - "url": "https://github.com/ArthurFiorette/prisma-json-types-generator?sponsor=1" - } - }, - "node_modules/promptly": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", - "integrity": "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==", - "dependencies": { - "read": "^1.0.4" - } - }, - "node_modules/proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", - "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==", - "dependencies": { - "agent-base": "^6.0.0", - "debug": "4", - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "lru-cache": "^5.1.1", - "pac-proxy-agent": "^5.0.0", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^5.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/proxy-agent/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==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/proxy-agent/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", - "dependencies": { - "mute-stream": "~0.0.4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/readable-stream": { - "version": "1.1.14", - "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", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", - "dependencies": { - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/readable-web-to-node-stream/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==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readable-web-to-node-stream/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==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-in-the-middle": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz", - "integrity": "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==", - "dependencies": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "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, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", - "dev": true, - "dependencies": { - "glob": "^10.2.5" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "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" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz", - "integrity": "sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.0", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "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", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "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==", - "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/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "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, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "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==" - }, - "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==", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", - "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "4", - "socks": "^2.3.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/socks/node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "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-width-cjs/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/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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/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, - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strtok3": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz", - "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^5.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/systeminformation": { - "version": "5.17.12", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.17.12.tgz", - "integrity": "sha512-I3pfMW2vue53u+X08BNxaJieaHkRoMMKjWetY9lbYJeWFaeWPO6P4FkNc4XOCX8F9vbQ0HqQ25RJoz3U/B7liw==", - "optional": true, - "os": [ - "darwin", - "linux", - "win32", - "freebsd", - "openbsd", - "netbsd", - "sunos", - "android" - ], - "bin": { - "systeminformation": "lib/cli.js" - }, - "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "Buy me a coffee", - "url": "https://www.buymeacoffee.com/systeminfo" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "peer": true - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/token-types": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", - "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/ts-mixer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", - "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "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/tscpaths": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/tscpaths/-/tscpaths-0.0.9.tgz", - "integrity": "sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w==", - "dev": true, - "dependencies": { - "commander": "^2.20.0", - "globby": "^9.2.0" - }, - "bin": { - "tscpaths": "cjs/index.js" - } - }, - "node_modules/tscpaths/node_modules/@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tscpaths/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/tscpaths/node_modules/dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "dependencies": { - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tscpaths/node_modules/fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "dependencies": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/tscpaths/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/tscpaths/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tscpaths/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/tscpaths/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tscpaths/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tscpaths/node_modules/path-type/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tscpaths/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tscpaths/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tv4": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", - "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/tx2": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tx2/-/tx2-1.0.5.tgz", - "integrity": "sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==", - "optional": true, - "dependencies": { - "json-stringify-safe": "^5.0.1" - } - }, - "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, - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/undici": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.0.tgz", - "integrity": "sha512-fR9RXCc+6Dxav4P9VV/sp5w3eFiSdOjJYsbtWfd4s5L5C4ogyuVpdKIVHeW0vV1MloM65/f7W45nR9ZxwVdyiA==", - "dependencies": { - "busboy": "^1.6.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "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, - "peer": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "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/vizion": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz", - "integrity": "sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==", - "dependencies": { - "async": "^2.6.3", - "git-node-fs": "^1.0.0", - "ini": "^1.3.5", - "js-git": "^0.7.8" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/vizion/node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/vm2": { - "version": "3.9.19", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz", - "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==", - "dependencies": { - "acorn": "^8.7.0", - "acorn-walk": "^8.2.0" - }, - "bin": { - "vm2": "bin/vm2" - }, - "engines": { - "node": ">=6.0" - } - }, - "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, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==", - "engines": { - "node": "*" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yamljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", - "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", - "dependencies": { - "argparse": "^1.0.7", - "glob": "^7.0.5" - }, - "bin": { - "json2yaml": "bin/json2yaml", - "yaml2json": "bin/yaml2json" - } - }, - "node_modules/yamljs/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/yamljs/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "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, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/anify-manager/package.json b/anify-manager/package.json index 51a6e2f..9fae23f 100644 --- a/anify-manager/package.json +++ b/anify-manager/package.json @@ -1,49 +1,26 @@ { - "devDependencies": { - "@types/node": "^18.16.2", - "@typescript-eslint/eslint-plugin": "^5.59.2", - "prettier": "2.8.8", - "prisma": "^4.13.0", - "prisma-json-types-generator": "^2.3.1", - "rimraf": "^5.0.0", - "ts-node": "^10.9.1", - "tsconfig-paths": "^4.2.0", - "tscpaths": "^0.0.9", - "tslib": "^2.5.0", - "typescript": "^4.9.5" - }, - "name": "anify-manager", - "description": "Manages Anify instances.", - "version": "1.0.0", - "source": "src/index.ts", - "scripts": { - "start": "node dist/index.js", - "start:bot": "ts-node -r tsconfig-paths/register src/scripts/startBot.ts", - "dev": "ts-node -r tsconfig-paths/register src/index.ts", - "test": "ts-node -r tsconfig-paths/register src/test.ts", - "build": "npm run build:ts && npm run lint", - "build:ts": "tsc --project tsconfig.json && tscpaths -p tsconfig.json -s ./src -o ./dist", - "clean": "rimraf dist/", - "eslint": "eslint --ext .ts src/** --fix", - "prettier": "prettier --write .", - "lint": "npm run prettier && npm run eslint" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Eltik/Anify.git" - }, - "author": "eltik", - "license": "ISC", - "bugs": { - "url": "https://github.com/Eltik/Anify/issues" - }, - "homepage": "https://github.com/Eltik/Anify#readme", - "dependencies": { - "axios": "^0.27.2", - "colors": "^1.4.0", - "crypto-js": "^4.1.1", - "discord.js": "^14.11.0", - "dotenv": "^16.0.3", - "pm2": "^5.3.0" - } -} + "name": "anify-manager-recode", + "module": "index.ts", + "type": "module", + "scripts": { + "start": "bun run dist/index.js", + "dev": "bun run src/index.ts", + "build": "bun build ./src/index.ts --outdir ./dist --target node", + "prettier": "prettier --write .", + "eslint": "eslint --ext .ts src/** --fix", + "lint": "bun run prettier && bun run eslint" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^6.7.0", + "@typescript-eslint/parser": "^6.7.0", + "bun-types": "latest", + "eslint": "^8.49.0" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "colors": "^1.4.0", + "eris": "^0.17.2" + } +} \ No newline at end of file diff --git a/anify-manager/src/bot/channels.json b/anify-manager/src/bot/channels.json deleted file mode 100644 index 090c0fa..0000000 --- a/anify-manager/src/bot/channels.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "errorChannel": "951146206036373565", - "logChannel": "1034958914363600967", - "suggestions": "1041158741556461619", - "status": "1036751152768884856", - "api": "1132046237357588533" -} \ No newline at end of file diff --git a/anify-manager/src/bot/colors.json b/anify-manager/src/bot/colors.json deleted file mode 100644 index bd84a9f..0000000 --- a/anify-manager/src/bot/colors.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": "#df5d5d", - "denied": "#ff6b6b", - "neutral": "#4cb875", - "success": "#84feb3" -} \ No newline at end of file diff --git a/anify-manager/src/bot/commands/assign.ts b/anify-manager/src/bot/commands/assign.ts deleted file mode 100644 index 6ac1d71..0000000 --- a/anify-manager/src/bot/commands/assign.ts +++ /dev/null @@ -1,62 +0,0 @@ -import config from "../colors.json"; -import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; -import axios from "axios"; -import { api, masterKey } from ".."; - -export default { - data: new SlashCommandBuilder() - .setName("assign") - .setDescription("Assigns an API key to an user.") - .addUserOption((option) => option.setName("user").setDescription("The user to assign the API key to").setRequired(true)) - .addStringOption((option) => option.setName("master-key").setDescription("Master key").setRequired(true)) - .addStringOption((option) => option.setName("key").setDescription("The key to assign").setRequired(true)), - async execute(interaction: CommandInteraction) { - const user = interaction.options.getUser("user"); - const master = interaction.options.get("master-key")?.value; - const key = interaction.options.get("key")?.value; - - if (master != masterKey) { - const embed = new EmbedBuilder() - .setColor(config.error as any) - .setDescription("You don't have permission to run this command!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - - if (!user) { - const embed = new EmbedBuilder() - .setColor(config.error as any) - .setDescription("You didn't specify a user!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - - try { - const { data } = await axios.get(`${api}/assign?id=${user.id}&key=${key}&apikey=${master}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - - if (data.error) { - const embed = new EmbedBuilder() - .setColor(config.error as any) - .setDescription(JSON.stringify(data)) - .setTimestamp(); - - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - - const embed = new EmbedBuilder() - .setColor(config.success as any) - .setDescription(`Successfully assigned key \`${key}\` to <@${user.id}>!`) - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - - await user.send(`Your API key has been assigned to \`${key}\`!`).catch((err) => { - interaction.channel?.send(`Failed to DM <@${user.id}>!`); - }); - } catch (e) { - console.error(e); - await interaction.channel?.send("Error."); - } - }, -}; diff --git a/anify-manager/src/bot/commands/get.ts b/anify-manager/src/bot/commands/get.ts deleted file mode 100644 index dcd414c..0000000 --- a/anify-manager/src/bot/commands/get.ts +++ /dev/null @@ -1,40 +0,0 @@ -import config from "../colors.json"; -import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; -import axios from "axios"; -import { api, masterKey } from ".."; - -export default { - data: new SlashCommandBuilder().setName("get").setDescription("Gets your personal API key."), - async execute(interaction: CommandInteraction) { - try { - const { data } = await axios.get(`${api}/key?id=${interaction.member?.user.id}&apikey=${masterKey}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - - if (data.error) { - const embed = new EmbedBuilder() - .setColor(config.error as any) - .setDescription(JSON.stringify(data)) - .setTimestamp(); - - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - - const string = ` - **Key**: \`${data.key}\` - **Request Count**: \`${data.requestCount}\` - **Created At**: \`${data.createdAt}\` - **Updated At**: \`${data.updatedAt}\` - `; - - const embed = new EmbedBuilder() - .setColor(config.neutral as any) - .setDescription(string) - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - } catch (e) { - console.error(e); - await interaction.reply("Error."); - } - }, -}; diff --git a/anify-manager/src/bot/commands/keys.ts b/anify-manager/src/bot/commands/keys.ts deleted file mode 100644 index 642084b..0000000 --- a/anify-manager/src/bot/commands/keys.ts +++ /dev/null @@ -1,81 +0,0 @@ -import config from "../colors.json"; -import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; -import axios from "axios"; -import { api, masterKey } from ".."; - -export default { - data: new SlashCommandBuilder() - .setName("keys") - .setDescription("Gets API keys.") - .addStringOption((option) => option.setName("key").setDescription("Master key").setRequired(true)) - .addIntegerOption((option) => option.setName("page").setDescription("Page to view")), - async execute(interaction: CommandInteraction) { - const key = interaction.options.get("key")?.value; - let page = (interaction.options.get("page")?.value as number) ?? 1; - - if (key != masterKey) { - const embed = new EmbedBuilder() - .setColor(config.error as any) - .setDescription("You don't have permission to run this command!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - - try { - const { data } = await axios.get(`${api}/keys?apikey=${key}`); - - const pageSize = 5; // Number of items to display per page - const totalPages = Math.ceil(data.length / pageSize); - - const pageContent: string[] = []; - - for (let i = 0; i < data.length; i += pageSize) { - const pageKeys = data.slice(i, i + pageSize); - let string = ""; - - for (const item of pageKeys) { - if (string.length !== 0) string += "======"; - string += ` - **User**: <@${item.id}> - **Key**: \`${item.key}\` - **Request Count**: \`${item.requestCount}\` - **Created At**: \`${item.createdAt}\` - **Updated At**: \`${item.updatedAt}\` - `; - } - - pageContent.push(string); - } - - if (page > totalPages) page = totalPages; - - page = Math.max(1, Math.min(page, totalPages)); // Ensure page number is within valid range - - const embed = new EmbedBuilder() - .setColor(config.neutral as any) - .setTitle(`Admin Keys (Page ${page}/${totalPages})`) - .setDescription(pageContent[page - 1]) - .setTimestamp(); - - await interaction.reply({ embeds: [embed], ephemeral: true }); - } catch (e) { - console.error(e); - await interaction.reply({ content: `Error executing command!`, ephemeral: true }); - } - }, -}; - -function formatKeys(keys) { - let string = ""; - for (const item of keys) { - if (string.length !== 0) string += "======"; - string += ` - **User**: <@${item.id}> - **Key**: \`${item.key}\` - **Request Count**: \`${item.requestCount}\` - **Created At**: \`${item.createdAt}\` - **Updated At**: \`${item.updatedAt}\` - `; - } - return string; -} diff --git a/anify-manager/src/bot/commands/ping.ts b/anify-manager/src/bot/commands/ping.ts deleted file mode 100644 index 8a2310e..0000000 --- a/anify-manager/src/bot/commands/ping.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CommandInteraction, SlashCommandBuilder } from "discord.js"; - -export default { - data: new SlashCommandBuilder().setName("ping").setDescription("Replies with Pong!"), - async execute(interaction: CommandInteraction) { - await interaction.reply("Pong!"); - }, -}; diff --git a/anify-manager/src/bot/commands/site.ts b/anify-manager/src/bot/commands/site.ts deleted file mode 100644 index 61b1c2f..0000000 --- a/anify-manager/src/bot/commands/site.ts +++ /dev/null @@ -1,16 +0,0 @@ -import config from "../colors.json"; -import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; - -const embed = new EmbedBuilder() - .setColor(config.neutral as any) - .setTitle("Anify") - .setDescription("Read an extensive library of manga and light novels or watch anime ad-free with customizable subtitles!\nhttps://anify.tv/") - .setURL("https://anify.tv/") - .setTimestamp(); - -export default { - data: new SlashCommandBuilder().setName("site").setDescription("Link to the Anify website."), - async execute(interaction: CommandInteraction) { - await interaction.reply({ embeds: [embed] }); - }, -}; diff --git a/anify-manager/src/bot/commands/stats.ts b/anify-manager/src/bot/commands/stats.ts deleted file mode 100644 index 2773905..0000000 --- a/anify-manager/src/bot/commands/stats.ts +++ /dev/null @@ -1,119 +0,0 @@ -import config from "../colors.json"; -import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; -import axios from "axios"; -import { list } from "@/src/manager"; -import { api, auth, frontend, masterKey } from ".."; - -let embed = new EmbedBuilder() - .setColor(config.neutral as any) - .setDescription("Loading...") - .setTimestamp(); - -async function getStats() { - const start = new Date(Date.now()); - const apiStats = (await axios(`${api}/stats?apikey=${masterKey}`)).data; - const end = new Date(Date.now()); - const apiTime = end.getTime() - start.getTime(); - - const start1 = new Date(Date.now()); - (await axios(`${auth}/`)).data; - const end1 = new Date(Date.now()); - const authTime = end1.getTime() - start1.getTime(); - - const start2 = new Date(Date.now()); - (await axios(`${frontend}/`)).data; - const end2 = new Date(Date.now()); - const frontendTime = end2.getTime() - start2.getTime(); - - const info: any = await list(); - - let infoString = ""; - - for (let i = 0; i < info.length; i++) { - const proc = info[i]; - - const pid = proc.pid; - const name = proc.name; - const upTime = new Date(proc.pm2_env.pm_uptime); // 1683653849001 - const createdAt = new Date(proc.pm2_env.created_at); // 1683653849001 - const restartTime = proc.pm2_env.restart_time; // 0 - const memory = proc.monit.memory; // 150683648 - const memoryInMb = memory / (1024 * 1024); - const memoryFormatted = memoryInMb < 1024 ? `${memoryInMb.toFixed(2)}mb` : `${(memoryInMb / 1024).toFixed(2)}GB`; - const cpu = proc.monit.cpu; // 0 - - infoString += ` - \`\`\`${name}\`\`\` - **PID**: \`${pid}\` - **Uptime**: \`${formatDate(upTime)}\` - **Started At**: \`${`${createdAt.getMonth() + 1}/${createdAt.getDate()}/${createdAt.getFullYear()} - ${createdAt.getHours()}:${createdAt.getMinutes()} ${createdAt.getHours() >= 12 ? "PM" : "AM"}`}\` - **Restarts**: \`${restartTime}\` - **Memory Usage**: \`${memoryFormatted}\` - **CPU Usage**: \`${cpu}%\` - `; - } - - const anime = apiStats.anime; - const manga = apiStats.manga; - const novels = apiStats.novels; - - embed = new EmbedBuilder() - .setColor(config.neutral as any) - .setTitle("Anify - Stats") - .setDescription( - ` - \`\`\`Media Count\`\`\` - **Anime**: \`${anime}\` - **Manga**: \`${manga}\` - **Novels**: \`${novels}\` - - \`\`\`Processes\`\`\` - **API Response**: \`${apiTime}ms\` - **Frontend Response**: \`${frontendTime}ms\` - **Auth Response**: \`${authTime}ms\` - ${infoString} - ` - ) - .setTimestamp(); -} - -function formatDate(date: Date) { - const seconds = Math.floor((new Date().getTime() - date.getTime()) / 1000); - - let interval = Math.floor(seconds / 31536000); - - if (interval >= 1) { - return interval + " years ago"; - } - - interval = Math.floor(seconds / 2592000); - if (interval >= 1) { - return interval + " months ago"; - } - - interval = Math.floor(seconds / 86400); - if (interval >= 1) { - return interval + " days ago"; - } - - interval = Math.floor(seconds / 3600); - if (interval >= 1) { - return interval + " hours ago"; - } - - interval = Math.floor(seconds / 60); - if (interval >= 1) { - return interval + " minutes ago"; - } - - return Math.floor(seconds) + " seconds ago"; -} - -export default { - data: new SlashCommandBuilder().setName("stats").setDescription("Get stats about the website."), - async execute(interaction: CommandInteraction) { - await interaction.reply({ embeds: [embed] }); - await getStats(); - await interaction.editReply({ embeds: [embed] }); - }, -}; diff --git a/anify-manager/src/bot/commands/unassign.ts b/anify-manager/src/bot/commands/unassign.ts deleted file mode 100644 index 55a2b57..0000000 --- a/anify-manager/src/bot/commands/unassign.ts +++ /dev/null @@ -1,47 +0,0 @@ -import config from "../colors.json"; -import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; -import axios from "axios"; -import { api, masterKey } from ".."; - -export default { - data: new SlashCommandBuilder() - .setName("unassign") - .setDescription("Unassigns an API key to an user.") - .addStringOption((option) => option.setName("master-key").setDescription("Master key").setRequired(true)) - .addStringOption((option) => option.setName("key").setDescription("The key to assign").setRequired(true)), - async execute(interaction: CommandInteraction) { - const master = interaction.options.get("master-key")?.value; - const key = interaction.options.get("key")?.value; - - if (master != masterKey) { - const embed = new EmbedBuilder() - .setColor(config.error as any) - .setDescription("You don't have permission to run this command!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - - try { - const { data } = await axios.get(`${api}/unassign?key=${key}&apikey=${master}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - - if (data.error) { - const embed = new EmbedBuilder() - .setColor(config.error as any) - .setDescription(JSON.stringify(data)) - .setTimestamp(); - - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - - const embed = new EmbedBuilder() - .setColor(config.success as any) - .setDescription(`Successfully unassigned key \`${key}\`!`) - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - } catch (e) { - await interaction.reply("Error."); - } - }, -}; diff --git a/anify-manager/src/bot/commands/updateKeys.ts b/anify-manager/src/bot/commands/updateKeys.ts deleted file mode 100644 index 17dfc47..0000000 --- a/anify-manager/src/bot/commands/updateKeys.ts +++ /dev/null @@ -1,42 +0,0 @@ -import config from "../colors.json"; -import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; -import axios from "axios"; -import { api, masterKey } from ".."; - -export default { - data: new SlashCommandBuilder() - .setName("update") - .setDescription("Updates API keys.") - .addStringOption((option) => option.setName("key").setDescription("Master key").setRequired(true)), - async execute(interaction: CommandInteraction) { - const key = interaction.options.get("key")?.value; - - if (key != masterKey) { - const embed = new EmbedBuilder() - .setColor(config.error as any) - .setDescription("You don't have permission to run this command!") - .setTimestamp(); - return await interaction.reply({ embeds: [embed], ephemeral: true }); - } - - try { - const { data } = await axios.get(`${api}/update-keys?apikey=${key}`); - - if (data.success === "true") { - const embed = new EmbedBuilder() - .setColor(config.neutral as any) - .setDescription("Success!") - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - } else { - const embed = new EmbedBuilder() - .setColor(config.neutral as any) - .setDescription("Error updating keys." + "\n" + data) - .setTimestamp(); - await interaction.reply({ embeds: [embed], ephemeral: true }); - } - } catch (e) { - await interaction.reply("Error."); - } - }, -}; diff --git a/anify-manager/src/bot/events/buttons.ts b/anify-manager/src/bot/events/buttons.ts deleted file mode 100644 index d346d56..0000000 --- a/anify-manager/src/bot/events/buttons.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { EmbedBuilder, Events } from "discord.js"; -import { client } from ".."; -import config from "../roles.json"; -import colorConfig from "../colors.json"; -import axios from "axios"; -import { api, masterKey } from ".."; -import { generateKey } from "@/src/manager"; - -export default client.on(Events.InteractionCreate, async (interaction) => { - if (interaction.isButton()) { - if (interaction.customId === "development-ping") { - await interaction.deferReply({ ephemeral: true }); - const hasRole = await toggleRole(interaction.guild, interaction.member, config.development_ping); - if (hasRole === null) { - const pingEmbed = new EmbedBuilder() - .setColor(colorConfig.error as any) - .setDescription("<@&" + config.development_ping + "> role doesn't exist. Please contact a staff member.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - return; - } - if (!hasRole) { - const pingEmbed = new EmbedBuilder() - .setColor(colorConfig.success as any) - .setDescription("Gave you the <@&" + config.development_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } else { - const pingEmbed = new EmbedBuilder() - .setColor(colorConfig.denied as any) - .setDescription("Removed the <@&" + config.development_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } - } - - if (interaction.customId === "scanlation-ping") { - await interaction.deferReply({ ephemeral: true }); - const hasRole = await toggleRole(interaction.guild, interaction.member, config.scanlation_ping); - if (hasRole === null) { - const pingEmbed = new EmbedBuilder() - .setColor(colorConfig.error as any) - .setDescription("<@&" + config.scanlation_ping + "> role doesn't exist. Please contact a staff member.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - return; - } - if (!hasRole) { - const pingEmbed = new EmbedBuilder() - .setColor(colorConfig.success as any) - .setDescription("Gave you the <@&" + config.scanlation_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } else { - const pingEmbed = new EmbedBuilder() - .setColor(colorConfig.denied as any) - .setDescription("Removed the <@&" + config.scanlation_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } - } - - if (interaction.customId === "announcement-ping") { - await interaction.deferReply({ ephemeral: true }); - const hasRole = await toggleRole(interaction.guild, interaction.member, config.announcement_ping); - if (hasRole === null) { - const pingEmbed = new EmbedBuilder() - .setColor(colorConfig.error as any) - .setDescription("<@&" + config.announcement_ping + "> role doesn't exist. Please contact a staff member.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - return; - } - if (!hasRole) { - const pingEmbed = new EmbedBuilder() - .setColor(colorConfig.success as any) - .setDescription("Gave you the <@&" + config.announcement_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } else { - const pingEmbed = new EmbedBuilder() - .setColor(colorConfig.denied as any) - .setDescription("Removed the <@&" + config.announcement_ping + "> role.") - .setTimestamp(); - interaction.editReply({ embeds: [pingEmbed] }); - } - } - - if (interaction.customId.includes("suggest")) { - await interaction.deferReply({ ephemeral: true }); - const time = 600000; - let timeTill = Date.now() / 1000; - timeTill += parseInt(String(time / 1000)); - - const suggestEmbed = new EmbedBuilder() - .setColor(colorConfig.success as any) - .setDescription("Make your suggestion now! You have until to make your suggestion.") - .setTimestamp(); - await interaction.editReply({ embeds: [suggestEmbed] }); - (interaction.channel as any).permissionOverwrites.edit((interaction.member as any).id, { SendMessages: true }); - setTimeout(() => { - (interaction.channel as any).permissionOverwrites.edit((interaction.member as any).id, { SendMessages: false }); - }, time); - } - - if (interaction.customId.includes("getkey")) { - await interaction.deferReply({ ephemeral: true }); - - const { data } = await axios.get(`${api}/key?id=${interaction.member?.user.id}&apikey=${masterKey}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - - if (data.error) { - // Generate key - const key = await generateKey(); - - const { data } = await axios.get(`${api}/assign?id=${interaction.member?.user.id}&key=${key}&apikey=${masterKey}`).catch((err) => { - return { data: { error: err.response?.data?.error ?? err.message } }; - }); - - if (data.error) { - // Return error - const errorEmbed = new EmbedBuilder() - .setColor(colorConfig.error as any) - .setDescription(`An error has occurred! Please contact a staff member. Error: \`${data.error}\``) - .setTimestamp(); - await interaction.editReply({ embeds: [errorEmbed] }); - return; - } - - const keyEmbed = new EmbedBuilder() - .setColor(colorConfig.success as any) - .setDescription(`Your key is \`${key}\`! You can run **/get** to display your current key.`) - .setTimestamp(); - await interaction.editReply({ embeds: [keyEmbed] }); - return; - } - - const embed = new EmbedBuilder() - .setColor(colorConfig.error as any) - .setDescription(`You already have a key! Key: \`${data.key}\``) - .setTimestamp(); - await interaction.editReply({ embeds: [embed] }); - } - } -}); - -async function toggleRole(guild, member, id) { - return new Promise(async function (resolve, reject) { - const role = guild.roles.cache.get(id); - if (!role) { - resolve(null); - return; - } - if (!member.roles.cache.has(role.id)) { - member.roles.add(role); - resolve(false); - } else { - member.roles.remove(role); - resolve(true); - } - }); -} diff --git a/anify-manager/src/bot/events/guildMemberAdd.ts b/anify-manager/src/bot/events/guildMemberAdd.ts deleted file mode 100644 index 9557b0a..0000000 --- a/anify-manager/src/bot/events/guildMemberAdd.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Events } from "discord.js"; -import { client } from ".."; -import colors from "colors"; -import config from "../roles.json"; - -export default client.on(Events.GuildMemberAdd, async (member) => { - const role = member.guild.roles.cache.find((role) => role.id === config.guest); - if (!role) { - return; - } - member.roles.add(role); - console.log(member.user.tag + " joined the server.".dim); -}); diff --git a/anify-manager/src/bot/events/guildMemberRemove.ts b/anify-manager/src/bot/events/guildMemberRemove.ts deleted file mode 100644 index 65ed060..0000000 --- a/anify-manager/src/bot/events/guildMemberRemove.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Events } from "discord.js"; -import { client } from ".."; -import colors from "colors"; - -export default client.on(Events.GuildMemberRemove, async (member) => { - console.log(member.user.tag + " left the server.".dim); -}); diff --git a/anify-manager/src/bot/events/interactionCreate.ts b/anify-manager/src/bot/events/interactionCreate.ts deleted file mode 100644 index 9156b69..0000000 --- a/anify-manager/src/bot/events/interactionCreate.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Events } from "discord.js"; -import { client } from ".."; -import colors from "colors"; - -export default client.on(Events.InteractionCreate, async (interaction) => { - if (!interaction.isChatInputCommand()) return; - - const command = (interaction.client as any).commands.get(interaction.commandName); - - if (!command) { - console.error(colors.red(`No command matching ${interaction.commandName} was found.`)); - return; - } - - try { - await command.execute(interaction); - } catch (error) { - console.error(colors.red(`Error executing ${interaction.commandName}`)); - console.error(error); - } -}); diff --git a/anify-manager/src/bot/events/messageCreate.ts b/anify-manager/src/bot/events/messageCreate.ts deleted file mode 100644 index 0c47f23..0000000 --- a/anify-manager/src/bot/events/messageCreate.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, Events } from "discord.js"; -import { client } from ".."; -import channels from "../channels.json"; -import configColors from "../colors.json"; - -let suggestion: any[] = []; - -const botId = process.env.CLIENT ?? ""; - -export default client.on(Events.MessageCreate, async (message) => { - if (message.channel.id === channels.suggestions && message.member?.id != botId) { - const messageDelete = message.channel.messages.cache.get(suggestion[suggestion.length - 1]); - suggestion = []; - - const avatarUrl = message.author.id && message.author.avatar ? `https://cdn.discordapp.com/avatars/${message.author.id}/${message.author.avatar}.png` : "https://i.waifu.pics/1y5O6HN.jpg"; - const suggestEmbed = new EmbedBuilder() - .setColor(configColors.neutral as any) - .setTitle("Suggestion By " + message.member?.user.tag) - .setDescription(message.content) - .setFooter({ text: message.member?.user.tag ?? "", iconURL: avatarUrl }) - .setTimestamp(); - const makeSuggestEmbed = new EmbedBuilder() - .setColor(configColors.neutral as any) - .setTitle("Make a Suggestion") - .setDescription("You will have **10 minutes** to finish making your suggestion before the channel will lock for you. Please also make sure your suggestion has not been made before. Troll suggestions will get deleted!") - .setFooter({ text: "Anify#7768", iconURL: "https://i.waifu.pics/1y5O6HN.jpg" }) - .setTimestamp(); - const suggestButton = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId("suggestion-" + message.id) - .setLabel("Suggest Something") - .setStyle(ButtonStyle.Success) - ); - if (messageDelete != undefined) { - messageDelete.delete(); - } - message.channel.send({ embeds: [suggestEmbed] }).then((msg) => { - message.channel.send({ embeds: [makeSuggestEmbed], components: [suggestButton as any] }).then((mssg) => { - suggestion.push(mssg.id); - }); - message.delete(); - - message.channel.messages.fetch(msg.id).then((mssg) => { - if (!mssg) { - return; - } - mssg.react("👍"); - mssg.react("👎"); - }); - (message.channel as any).permissionOverwrites.edit(message.member?.id, { SendMessages: false }); - }); - } -}); diff --git a/anify-manager/src/bot/events/ready.ts b/anify-manager/src/bot/events/ready.ts deleted file mode 100644 index 0d9f997..0000000 --- a/anify-manager/src/bot/events/ready.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Events } from "discord.js"; -import { client } from ".."; -import colors from "colors"; - -export default client.once(Events.ClientReady, (c) => { - console.log(colors.green(`Ready! Logged in as ${c.user.tag}`)); -}); diff --git a/anify-manager/src/bot/events/status.ts b/anify-manager/src/bot/events/status.ts deleted file mode 100644 index 6ec7d08..0000000 --- a/anify-manager/src/bot/events/status.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, TextChannel } from "discord.js"; -import { client } from ".."; -import configColor from "../colors.json"; -import channels from "../channels.json"; -import axios from "axios"; - -const frontend = process.env.FRONTEND ?? ""; -const api = process.env.API ?? ""; -const auth = process.env.AUTH ?? ""; - -const updateStatusEmbed = async () => { - const channelId = channels.status; // Replace with your channel ID - const channel = await client.channels.fetch(channelId); - - const req1 = await axios(frontend).catch((err) => { - return null; - }); - const req2 = await axios(api).catch((err) => { - return null; - }); - const req3 = await axios(auth).catch((err) => { - return null; - }); - - const statusEmbed = new EmbedBuilder() - .setColor(configColor.neutral as any) - .setTitle("Status") - .setDescription(`**Frontend**: ${req1 ? "✅" : "❌"}\n**Backend**: ${req2 ? "✅" : "❌"}\n**Authentication**: ${req3 ? "✅" : "❌"}`); - - if (!channel) { - console.error("Channel not found."); - return; - } - - if (channel instanceof TextChannel) { - const messages = await channel.messages.fetch(); - const lastMessage = messages.first(); - - if (lastMessage && lastMessage.author.id === client.user?.id) { - await lastMessage.edit({ embeds: [statusEmbed] }); - } else { - await channel.send({ embeds: [statusEmbed] }); - } - } -}; - -const createKeyButtons = async () => { - const channelId = channels.api; // Replace with your channel ID - const channel = await client.channels.fetch(channelId); - - const keyEmbed = new EmbedBuilder() - .setColor(configColor.neutral as any) - .setTitle("Get API Key") - .setDescription("Get your own API key for development! API documentation can be viewed [here](https://docs.anify.tv). Only one API key can be generated per user. Abusing this system will result in a permanent ban from the API."); - - const keyButton = new ActionRowBuilder().addComponents(new ButtonBuilder().setCustomId("getkey").setLabel("Get Key").setStyle(ButtonStyle.Primary)); - - if (!channel) { - console.error("Channel not found."); - return; - } - - if (channel instanceof TextChannel) { - const messages = await channel.messages.fetch(); - const lastMessage = messages.first(); - - if (lastMessage && lastMessage.author.id === client.user?.id) { - return; - } else { - await channel.send({ embeds: [keyEmbed], components: [keyButton as any] }); - } - } -}; - -async function runStatusEmbed() { - setTimeout(async () => { - await updateStatusEmbed(); - await createKeyButtons(); - - setInterval(() => { - updateStatusEmbed(); - createKeyButtons(); - }, 300000); - }, 10000); -} - -export default runStatusEmbed(); diff --git a/anify-manager/src/bot/index.ts b/anify-manager/src/bot/index.ts deleted file mode 100644 index 61334df..0000000 --- a/anify-manager/src/bot/index.ts +++ /dev/null @@ -1,104 +0,0 @@ -// Require the necessary discord.js classes -import { ActivityType, Client, Collection, GatewayIntentBits, Partials, REST, Routes } from "discord.js"; -import colors from "colors"; -import { readdirSync } from "fs"; -import { join } from "path"; - -const token = process.env.TOKEN ?? ""; -const clientId = process.env.CLIENT ?? ""; -const guildId = process.env.GUILD ?? ""; - -export const masterKey = process.env.MASTER_KEY ?? ""; -export const api = process.env.API ?? ""; -export const auth = process.env.AUTH ?? ""; -export const frontend = process.env.FRONTEND ?? ""; - -export const client = new Client({ - shards: "auto", - allowedMentions: { - parse: [], - repliedUser: true, - }, - intents: [GatewayIntentBits.GuildMembers, GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildMessageReactions, GatewayIntentBits.MessageContent], - presence: { - activities: [{ name: "Anime", type: ActivityType.Watching }], - status: "online", - }, - partials: [Partials.Message, Partials.Channel, Partials.Reaction, Partials.GuildMember], -}); - -export async function registerCommands() { - const commands: any[] = []; - - const rest = new REST().setToken(token); - const existingCommands: any = await rest.get(Routes.applicationGuildCommands(clientId, guildId)); - - existingCommands.forEach((command: any) => { - commands.push(command); - console.log(colors.gray("Registered ") + colors.blue(`/${command.name}`) + colors.gray(".")); - }); - - for (const file of readdirSync(join(__dirname, "./commands"))) { - const filePath = join(join(__dirname, "./commands"), file); - const { default: command } = await import(filePath); - // Set a new item in the Collection with the key as the command name and the value as the exported module - if ("data" in command && "execute" in command) { - let canPush = true; - for (let i = 0; i < existingCommands.length; i++) { - if (command.data.name === existingCommands[i].name) { - console.log(colors.yellow(`[WARNING] The command at ${filePath} is already registered. Skipping...`)); - canPush = false; - break; - } - } - if (canPush) { - commands.push(command.data.toJSON()); - console.log(colors.gray("Registered ") + colors.blue(`/${command.data.name}`) + colors.gray(".")); - } - } else { - console.log(colors.yellow(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`)); - } - } - - // If there are new commands to register - if (commands.length > 0) { - try { - console.log(colors.yellow(`Started refreshing ${commands.length} application (/) commands.`)); - - // The post method is used to create new commands without overwriting existing ones - const data: any = await rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands }); - - console.log(colors.green(`Successfully registered ${data.length} new application (/) commands.`)); - } catch (error) { - console.error(error); - } - } else { - console.log(colors.gray("No new commands to register.")); - } -} - -export async function loadCommands() { - (client as any).commands = new Collection(); - - for (const file of readdirSync(join(__dirname, "./commands"))) { - const filePath = join(join(__dirname, "./commands"), file); - const { default: command } = await import(filePath); - // Set a new item in the Collection with the key as the command name and the value as the exported module - if ("data" in command && "execute" in command) { - (client as any).commands.set(command.data.name, command); - console.log(colors.gray("Registered command ") + colors.blue(`/${command.data.name}`) + colors.gray(".")); - } - } -} - -export async function loadEvents() { - for (const file of readdirSync(join(__dirname, "./events"))) { - const filePath = join(join(__dirname, "./events"), file); - await import(filePath); - console.log(colors.gray("Registered event ") + colors.blue(`${file}`) + colors.gray(".")); - } -} - -export async function login() { - await client.login(token); -} diff --git a/anify-manager/src/bot/roles.json b/anify-manager/src/bot/roles.json deleted file mode 100644 index 497c5ed..0000000 --- a/anify-manager/src/bot/roles.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "moderation": "950965073281708044", - "guest": "950964334983520257", - "muted": "952228969724383292", - "announcement_ping": "1040385046068068403", - "development_ping": "1040384998701797537", - "scanlation_ping": "1040385081094705252" -} \ No newline at end of file diff --git a/anify-manager-recode/src/config.ts b/anify-manager/src/config.ts similarity index 79% rename from anify-manager-recode/src/config.ts rename to anify-manager/src/config.ts index d6fea22..bbdd7f2 100644 --- a/anify-manager-recode/src/config.ts +++ b/anify-manager/src/config.ts @@ -13,12 +13,12 @@ export const buildCommands: { export const runCommands: { [key: string]: string; } = { - anify: "npm run i", + anify: "npm run start", }; export const repositories = [ { - url: "https://github.com/Eltik/Anify", + url: "https://github.com/Eltik/Anify/tree/bun", name: "anify", }, ]; diff --git a/anify-manager-recode/src/discord/client.ts b/anify-manager/src/discord/client.ts similarity index 100% rename from anify-manager-recode/src/discord/client.ts rename to anify-manager/src/discord/client.ts diff --git a/anify-manager-recode/src/discord/commands/anify/list.ts b/anify-manager/src/discord/commands/anify/list.ts similarity index 100% rename from anify-manager-recode/src/discord/commands/anify/list.ts rename to anify-manager/src/discord/commands/anify/list.ts diff --git a/anify-manager-recode/src/discord/commands/anify/pull.ts b/anify-manager/src/discord/commands/anify/pull.ts similarity index 82% rename from anify-manager-recode/src/discord/commands/anify/pull.ts rename to anify-manager/src/discord/commands/anify/pull.ts index 45afa8e..70950f1 100644 --- a/anify-manager-recode/src/discord/commands/anify/pull.ts +++ b/anify-manager/src/discord/commands/anify/pull.ts @@ -6,12 +6,12 @@ export default { name: "pull", schema: { name: "pull", - description: "pull the latest repos from github under the folder label.", + description: "Pull the latest repository from GitHub under the folder label.", type: Constants.ApplicationCommandTypes.CHAT_INPUT, options: [ { name: "label", - description: "the label of the folder which the latest repos will be in.", + description: "The label of the folder which the latest repository will be in.", type: Constants.ApplicationCommandOptionTypes.STRING, required: true, }, @@ -23,7 +23,6 @@ export default { if (!interaction.acknowledged) await interaction.acknowledge(1); const data = await build(value, ["anify"], 0); - console.log(data); interaction.editOriginalMessage(response.run.error.message(JSON.stringify(data))); }, diff --git a/anify-manager/src/discord/commands/anify/run.ts b/anify-manager/src/discord/commands/anify/run.ts new file mode 100644 index 0000000..e3f5f7f --- /dev/null +++ b/anify-manager/src/discord/commands/anify/run.ts @@ -0,0 +1,73 @@ +import * as response from "../../responses/anify"; +import { run } from "../../../utils/pm2"; +import view from "../../../utils/fs/view"; + +import running from "./running"; +import { AutocompleteInteraction, Client, CommandInteraction, ComponentInteraction, Constants, TextableChannel } from "eris"; + +const logic = async (value?: string) => { + const list = view(); + if (value == "latest" || !value) value = list[0].name; + const [first, second] = await run(value); + + if (first.error || second?.error) return response.run.error.message(`${first.error} - ${first.data} \n ${second.error} - ${second.data}`); + + return response.run.message([second, first]); +}; + +export default { + name: "run", + schema: { + name: "run", + description: "Starts a new process.", + type: Constants.ApplicationCommandTypes.CHAT_INPUT, + options: [ + { + name: "select", + description: "Select a label to run.", + type: Constants.ApplicationCommandOptionTypes.STRING, + autocomplete: true, + }, + ], + }, + autocomplete: (client: Client, interaction: AutocompleteInteraction) => { + // get the current text the user has sent + const firstOptions = interaction.data.options[0]; + let secondOptions: any = {}; + let text: string; + + if ("options" in firstOptions) { + secondOptions = firstOptions?.options?.at(0); + } + if ("value" in secondOptions) { + text = secondOptions?.value as string; + } + + const list = view().filter((x) => x.name.includes(text)); + + interaction.result([ + ...list.map((x) => ({ + name: x.name, + value: x.name, + })), + { + name: "latest", + value: "latest", + }, + ]); + }, + on: async (client: Client, interaction: CommandInteraction) => { + // @ts-ignore + let value = interaction?.data?.options?.[0]?.options?.[0]?.value as string; + + const embed = await logic(value); + interaction.createMessage(embed); + }, + onInteraction: async (client: Client, interaction: ComponentInteraction) => { + // This is a button to make view the running scripts + if (interaction.data.component_type === 2) { + interaction.createMessage(await running.logic()); + } + }, + logic, +}; diff --git a/anify-manager/src/discord/commands/anify/running.ts b/anify-manager/src/discord/commands/anify/running.ts new file mode 100644 index 0000000..60a94e1 --- /dev/null +++ b/anify-manager/src/discord/commands/anify/running.ts @@ -0,0 +1,40 @@ +import * as response from "../../responses/anify"; +import { kill, list } from "../../../utils/pm2"; +import run from "./run"; +import { Client, CommandInteraction, ComponentInteraction, Constants, TextableChannel } from "eris"; + +const logic = async () => { + const { data } = await list(); + // remove element if name = "discord-bot" + const index = data.findIndex((x) => x.name == "discord-bot"); + if (index > -1) data.splice(index, 1); + + if (!data.length) return response.viewRunningRepo.error.message("No **Running** Scripts found!"); + return response.viewRunningRepo.message(data.map((x) => x.name || "N/A")); +}; + +export default { + name: "running", + schema: { + name: "running", + description: "View the current running processes of PM2.", + type: Constants.ApplicationCommandTypes.CHAT_INPUT, + }, + logic: logic, + on: async (client: Client, interaction: CommandInteraction) => { + await interaction.createMessage(await logic()); + }, + onInteraction: async (client: Client, interaction: ComponentInteraction) => { + if (interaction.data.component_type === 2) { + if (interaction.data.custom_id === "kato-run") { + return await interaction.createMessage(await run.logic()); + } + + const [data] = await kill(interaction.data.custom_id); + if (data.error) return interaction.createMessage(response.stopRepo.error.message(data.error as string)); + + // update original message + await interaction.editParent(await logic()); + } + }, +}; diff --git a/anify-manager-recode/src/discord/responses.ts b/anify-manager/src/discord/responses.ts similarity index 100% rename from anify-manager-recode/src/discord/responses.ts rename to anify-manager/src/discord/responses.ts diff --git a/anify-manager-recode/src/discord/responses/anify.ts b/anify-manager/src/discord/responses/anify.ts similarity index 96% rename from anify-manager-recode/src/discord/responses/anify.ts rename to anify-manager/src/discord/responses/anify.ts index fb63383..2694027 100644 --- a/anify-manager-recode/src/discord/responses/anify.ts +++ b/anify-manager/src/discord/responses/anify.ts @@ -27,7 +27,7 @@ export const run: customEmbed< > = createCustomEmbed({ embeds: (repos) => [ { - title: repos.map((x) => (x.error ? `${x.error} - ${x.data}` : `Started ${x.data}`)).join("\n"), + title: repos.map((x) => (x?.error ? `${x?.error} - ${x?.data}` : `Started ${x?.data}`)).join("\n"), }, ], components: () => [ diff --git a/anify-manager-recode/src/discord/types.d.ts b/anify-manager/src/discord/types.d.ts similarity index 100% rename from anify-manager-recode/src/discord/types.d.ts rename to anify-manager/src/discord/types.d.ts diff --git a/anify-manager-recode/src/env.ts b/anify-manager/src/env.ts similarity index 100% rename from anify-manager-recode/src/env.ts rename to anify-manager/src/env.ts diff --git a/anify-manager/src/index.ts b/anify-manager/src/index.ts index 4ac7785..475e325 100644 --- a/anify-manager/src/index.ts +++ b/anify-manager/src/index.ts @@ -1,70 +1 @@ -import dotenv from "dotenv"; -dotenv.config(); -import colors from "colors"; -import { loadCommands, loadEvents, login, registerCommands } from "./bot"; -import { Process, connect, remove, start } from "./manager"; - -(async function () { - try { - await Promise.all([startManager(), startBot()]); - } catch (err) { - console.error(colors.red("Error: "), err); - } -})(); - -async function startManager() { - await connect(); - await Promise.all([start(Process.FRONTEND), start(Process.BACKEND), start(Process.AUTH)]).catch((err) => { - console.error(colors.red("Error: "), err); - }); - console.log(colors.green("Started process manager.")); -} - -async function startBot() { - if (!process.env.TOKEN) { - console.log(colors.red("No Discord token provided. Discord bot will not be started up.")); - return; - } - if (!process.env.CLIENT) { - console.log(colors.red("No Discord client ID provided. Discord bot will not be started up.")); - return; - } - if (!process.env.GUILD) { - console.log(colors.red("No Discord guild ID provided. Discord bot will not be started up.")); - return; - } - if (!process.env.FRONTEND) { - console.log(colors.yellow("WARNING: Frontend URL not provided. Discord bot will likely have issues. Please provide the URL in the .env file.")); - } - if (!process.env.API) { - console.log(colors.yellow("WARNING: API URL not provided. Discord bot will likely have issues. Please provide the URL in the .env file.")); - } - if (!process.env.AUTH) { - console.log(colors.yellow("WARNING: Auth URL not provided. Discord bot will likely have issues. Please provide the URL in the .env file.")); - } - if (!process.env.MASTER_KEY) { - console.log(colors.yellow("WARNING: Master key not provided. Discord bot will likely have issues. Please provide the key in the .env file.")); - } - await Promise.all([registerCommands(), loadCommands(), loadEvents(), login()]).catch((err) => { - console.error(colors.red("Error: "), err); - }); -} - -process.on("beforeExit", async () => { - console.log(colors.red("Stopping services...")); - await Promise.all([remove(Process.FRONTEND), remove(Process.BACKEND), remove(Process.AUTH)]).catch((err) => { - console.error(colors.red("Error: "), err); - }); -}); - -process.on("unhandledRejection", (err) => { - console.error(colors.red("Unhandled Promise rejection: "), err); -}); - -process.on("SIGINT", async () => { - console.log(colors.red("Stopping services...")); - await Promise.all([remove(Process.FRONTEND), remove(Process.BACKEND)]).catch((err) => { - console.error(colors.red("Error: "), err); - }); - process.exit(); -}); +import "./discord/client"; diff --git a/anify-manager/src/manager/index.ts b/anify-manager/src/manager/index.ts deleted file mode 100644 index b9d6202..0000000 --- a/anify-manager/src/manager/index.ts +++ /dev/null @@ -1,139 +0,0 @@ -import pm2 from "pm2"; -import colors from "colors"; -import * as fs from "fs/promises"; -import { join } from "path"; -import { exec } from "child_process"; - -export async function connect() { - return new Promise((resolve, reject) => { - pm2.connect(async (err) => { - if (err) { - console.error(err); - process.exit(2); - } - - resolve(true); - }); - }); -} - -export async function list() { - return new Promise((resolve, reject) => { - pm2.list((err, list) => { - if (err) return reject(err); - resolve(list); - }); - }); -} - -export async function start(process: Process) { - if (process === Process.FRONTEND) { - return new Promise((resolve, reject) => { - pm2.start( - { - script: "cd ../anify-frontend && npm run start", - name: "anify-frontend", - }, - (err, apps) => { - if (err) { - console.error(colors.red("Error starting up frontend.")); - console.error(err); - pm2.disconnect(); - reject(err); - return; - } - resolve(true); - } - ); - }); - } else if (process === Process.BACKEND) { - return new Promise((resolve, reject) => { - pm2.start( - { - script: "cd ../anify-backend && NODE_ENV=production npm run start", - name: "anify-backend", - }, - (err, apps) => { - if (err) { - console.error(colors.red("Error starting up backend.")); - console.error(err); - pm2.disconnect(); - reject(err); - return; - } - resolve(true); - } - ); - }); - } else if (process === Process.AUTH) { - return new Promise((resolve, reject) => { - pm2.start( - { - script: "cd ../anify-auth && npm run start", - name: "anify-auth", - }, - (err, apps) => { - if (err) { - console.error(colors.red("Error starting up auth.")); - console.error(err); - pm2.disconnect(); - reject(err); - return; - } - resolve(true); - } - ); - }); - } -} - -export async function reload(process: Process) { - return new Promise((resolve, reject) => { - pm2.reload(process, (err, proc) => { - if (err) return reject(err); - resolve(true); - }); - }); -} - -export async function remove(process: Process) { - return new Promise((resolve, reject) => { - pm2.delete(process, (err, proc) => { - if (err) return reject(err); - resolve(true); - }); - }); -} - -export async function stop(process: Process) { - return new Promise((resolve, reject) => { - pm2.stop(process, (err, proc) => { - if (err) return reject(err); - resolve(true); - }); - }); -} - -export async function generateKey(): Promise { - return new Promise((resolve, reject) => { - exec("cd ../anify-backend && npm run create:key", (error, stdout, stderr) => { - if (error) { - console.error(`Error executing command: ${error.message}`); - reject(error); - } else if (stderr) { - console.error(`Command error: ${stderr}`); - reject(new Error(stderr)); - } else { - const lines = stdout.trim().split("\n"); - const key = lines[lines.length - 1].trim(); - resolve(key); - } - }); - }); -} - -export const enum Process { - FRONTEND = "anify-frontend", - BACKEND = "anify-backend", - AUTH = "anify-auth", -} diff --git a/anify-manager/src/scripts/startBot.ts b/anify-manager/src/scripts/startBot.ts deleted file mode 100644 index bfe2a0f..0000000 --- a/anify-manager/src/scripts/startBot.ts +++ /dev/null @@ -1,11 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import colors from "colors"; -import { loadCommands, loadEvents, login, registerCommands } from "../bot"; - -(async function () { - await Promise.all([registerCommands(), loadCommands(), loadEvents(), login()]).catch((err) => { - console.error(colors.red("Error: "), err); - }); -})(); diff --git a/anify-manager-recode/src/utils/fs/health.ts b/anify-manager/src/utils/fs/health.ts similarity index 100% rename from anify-manager-recode/src/utils/fs/health.ts rename to anify-manager/src/utils/fs/health.ts diff --git a/anify-manager-recode/src/utils/fs/view.ts b/anify-manager/src/utils/fs/view.ts similarity index 100% rename from anify-manager-recode/src/utils/fs/view.ts rename to anify-manager/src/utils/fs/view.ts diff --git a/anify-manager-recode/src/utils/pm2/build.ts b/anify-manager/src/utils/pm2/build.ts similarity index 96% rename from anify-manager-recode/src/utils/pm2/build.ts rename to anify-manager/src/utils/pm2/build.ts index 4ff425f..98322f2 100644 --- a/anify-manager-recode/src/utils/pm2/build.ts +++ b/anify-manager/src/utils/pm2/build.ts @@ -21,6 +21,8 @@ export default async function build(label: string, name: string[], count: number } try { + if (!existsSync("builds")) mkdirSync("builds"); + const buildPath = `builds/${label}-${count}`; const logPath = `${buildPath}/logs`; @@ -37,7 +39,6 @@ export default async function build(label: string, name: string[], count: number output?.split("\n").forEach((line: string) => { logStream?.write(msg + line + "\n"); - console.log(msg + line); }); }; @@ -56,7 +57,7 @@ export default async function build(label: string, name: string[], count: number writeToLogStream(output.stdout, repo.name); writeToLogStream(output.stderr, repo.name); - localCommand = `cd ${buildPath}/${repo.name} && pnpm install`; + localCommand = `cd ${buildPath}/${repo.name} && npm install`; output = await execPromise(localCommand); writeToLogStream(output.stdout, repo.name); diff --git a/anify-manager-recode/src/utils/pm2/index.ts b/anify-manager/src/utils/pm2/index.ts similarity index 65% rename from anify-manager-recode/src/utils/pm2/index.ts rename to anify-manager/src/utils/pm2/index.ts index 181b424..a5f786c 100644 --- a/anify-manager-recode/src/utils/pm2/index.ts +++ b/anify-manager/src/utils/pm2/index.ts @@ -4,4 +4,6 @@ import run from "./run"; import build from "./build"; import update from "./update"; +export const runningProcesses: Map = new Map(); + export { list, kill, run, build, update }; diff --git a/anify-manager-recode/src/utils/pm2/kill.ts b/anify-manager/src/utils/pm2/kill.ts similarity index 51% rename from anify-manager-recode/src/utils/pm2/kill.ts rename to anify-manager/src/utils/pm2/kill.ts index bc34883..dcf7e17 100644 --- a/anify-manager-recode/src/utils/pm2/kill.ts +++ b/anify-manager/src/utils/pm2/kill.ts @@ -1,5 +1,4 @@ -import pm2 from "pm2"; -import initalizePm2 from "./initalizePm2"; +import { runningProcesses } from "."; interface IResponse { error?: string; @@ -7,8 +6,6 @@ interface IResponse { } const kill = async (names: string | number | (string | number)[]): Promise => { - await initalizePm2(); - if (!Array.isArray(names)) { names = [names]; } @@ -16,13 +13,8 @@ const kill = async (names: string | number | (string | number)[]): Promise { return new Promise((resolve, reject) => { - pm2.delete(name, (err, results) => { - if (err) { - resolve({ error: err.message as string, data: name as string }); - } else { - resolve({ data: "success" }); - } - }); + runningProcesses.get(String(name))?.kill(); + resolve({ data: `killed ${name}` }); }); }) ); diff --git a/anify-manager/src/utils/pm2/list.ts b/anify-manager/src/utils/pm2/list.ts new file mode 100644 index 0000000..629f6ae --- /dev/null +++ b/anify-manager/src/utils/pm2/list.ts @@ -0,0 +1,25 @@ +import { runningProcesses } from "."; + +export interface IResponse extends Object { + error?: string; + data: { + name?: string; + pid?: number; + }[]; +} + +const list = async (): Promise => { + return new Promise((resolve, reject) => { + const data = Array.from(runningProcesses.keys()).map((x) => { + if (!x) return; + return { name: x, pid: runningProcesses.get(x)?.pid } + }).filter((x) => x) as any; + + // Also get all processes that use node + + resolve({ data }); + }); +}; + +export default list; +export { list }; diff --git a/anify-manager-recode/src/utils/pm2/run.ts b/anify-manager/src/utils/pm2/run.ts similarity index 52% rename from anify-manager-recode/src/utils/pm2/run.ts rename to anify-manager/src/utils/pm2/run.ts index faef9fe..f6690ba 100644 --- a/anify-manager-recode/src/utils/pm2/run.ts +++ b/anify-manager/src/utils/pm2/run.ts @@ -1,8 +1,8 @@ import { runCommands } from "../../config"; -import initalizePm2 from "./initalizePm2"; import { promisify } from "util"; -import pm2 from "pm2"; import fs from "fs"; +import { runningProcesses } from "."; +import { spawn } from "node:child_process"; interface BuildDetail { error?: string; @@ -10,37 +10,40 @@ interface BuildDetail { } const run = async (folderName: string): Promise => { - await initalizePm2(); - const builds = (await promisify(fs.readdir)("./builds")) as any[]; const buildStats = await Promise.all(builds.map((build) => promisify(fs.stat)(`./builds/${build}`))); const latestBuild = folderName ?? builds[buildStats.filter((stat: any) => stat.isDirectory()).length - 1]; const keys = Object.keys(runCommands); const buildDetails: BuildDetail[] = []; + for (let i = 0; i < keys.length; i++) { const key = keys[i]; const value = runCommands[key]; await new Promise((resolve, reject) => { - pm2.start( - { - script: `pnpm`, - args: value.split(" "), - cwd: `./builds/${latestBuild}/${key}`, - name: latestBuild + "-" + key, - }, - (err, apps) => { - if (err) { - console.log(err); - buildDetails.push({ error: err.message }); - } else { - buildDetails.push({ data: `running ${latestBuild}, ${key}` }); - } - - resolve(); - } - ); + // Startup process + const childProcess = spawn("pnpm", value.split(" "), { + cwd: `./builds/${latestBuild}/${key}`, + detached: true + }); + + childProcess.unref(); + + runningProcesses.set(latestBuild + "-" + key, childProcess); + + childProcess.stdout.on("data", (data) => { + buildDetails.push({ data: data.toString() }); + }); + + childProcess.on("error", (err) => { + console.error(err); + buildDetails.push({ error: err.message }); + }); + + buildDetails.push({ data: `running ${latestBuild}, ${key}` }); + + resolve() }); } diff --git a/anify-manager-recode/src/utils/pm2/update.ts b/anify-manager/src/utils/pm2/update.ts similarity index 97% rename from anify-manager-recode/src/utils/pm2/update.ts rename to anify-manager/src/utils/pm2/update.ts index b20082d..017ffd7 100644 --- a/anify-manager-recode/src/utils/pm2/update.ts +++ b/anify-manager/src/utils/pm2/update.ts @@ -2,7 +2,7 @@ import { buildCommands, repositories } from "../../config"; import fs from "fs"; import { exec, ChildProcess } from "child_process"; import { promisify } from "util"; -import { WriteStream, copyFileSync, createWriteStream, existsSync, mkdirSync, readFileSync } from "fs"; +import { copyFileSync, createWriteStream, existsSync, mkdirSync } from "fs"; const execPromise = promisify(exec); diff --git a/anify-manager/tsconfig.json b/anify-manager/tsconfig.json index f3b9dff..388a057 100644 --- a/anify-manager/tsconfig.json +++ b/anify-manager/tsconfig.json @@ -1,33 +1,22 @@ { "compilerOptions": { + "lib": ["ESNext"], + "module": "esnext", "target": "esnext", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, "strict": true, - "forceConsistentCasingInFileNames": true, - "esModuleInterop": true, - "module": "CommonJS", - "moduleResolution": "node", - "resolveJsonModule": true, - "noImplicitAny": false, - "isolatedModules": false, - "allowSyntheticDefaultImports": true, + "downlevelIteration": true, + "skipLibCheck": true, "jsx": "preserve", - "incremental": true, - "declaration": true, - "baseUrl": ".", - "paths": { - "@/*": ["./*"], - "database": ["./src/database"] - }, - "outDir": "./dist" - }, - "include": ["src"], - "exclude": ["node_modules", "dist"], - "ts-node": { - "compilerOptions": { - "module": "commonjs" - } + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [ + "bun-types" // add Bun global + ] } } diff --git a/anify-manager/yarn.lock b/anify-manager/yarn.lock deleted file mode 100644 index e607a3e..0000000 --- a/anify-manager/yarn.lock +++ /dev/null @@ -1,3362 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@cspotcode/source-map-support@^0.8.0": - 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== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@discordjs/builders@^1.6.3": - version "1.6.3" - resolved "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.3.tgz" - integrity sha512-CTCh8NqED3iecTNuiz49mwSsrc2iQb4d0MjMdmS/8pb69Y4IlzJ/DIy/p5GFlgOrFbNO2WzMHkWKQSiJ3VNXaw== - dependencies: - "@discordjs/formatters" "^0.3.1" - "@discordjs/util" "^0.3.1" - "@sapphire/shapeshift" "^3.8.2" - discord-api-types "^0.37.41" - fast-deep-equal "^3.1.3" - ts-mixer "^6.0.3" - tslib "^2.5.0" - -"@discordjs/collection@^1.5.1": - version "1.5.1" - resolved "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.1.tgz" - integrity sha512-aWEc9DCf3TMDe9iaJoOnO2+JVAjeRNuRxPZQA6GVvBf+Z3gqUuWYBy2NWh4+5CLYq5uoc3MOvUQ5H5m8CJBqOA== - -"@discordjs/formatters@^0.3.1": - version "0.3.1" - resolved "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.1.tgz" - integrity sha512-M7X4IGiSeh4znwcRGcs+49B5tBkNDn4k5bmhxJDAUhRxRHTiFAOTVUNQ6yAKySu5jZTnCbSvTYHW3w0rAzV1MA== - dependencies: - discord-api-types "^0.37.41" - -"@discordjs/rest@^1.7.1": - version "1.7.1" - resolved "https://registry.npmjs.org/@discordjs/rest/-/rest-1.7.1.tgz" - integrity sha512-Ofa9UqT0U45G/eX86cURQnX7gzOJLG2oC28VhIk/G6IliYgQF7jFByBJEykPSHE4MxPhqCleYvmsrtfKh1nYmQ== - dependencies: - "@discordjs/collection" "^1.5.1" - "@discordjs/util" "^0.3.0" - "@sapphire/async-queue" "^1.5.0" - "@sapphire/snowflake" "^3.4.2" - discord-api-types "^0.37.41" - file-type "^18.3.0" - tslib "^2.5.0" - undici "^5.22.0" - -"@discordjs/util@^0.3.0", "@discordjs/util@^0.3.1": - version "0.3.1" - resolved "https://registry.npmjs.org/@discordjs/util/-/util-0.3.1.tgz" - integrity sha512-HxXKYKg7vohx2/OupUN/4Sd02Ev3PBJ5q0gtjdcvXb0ErCva8jNHWfe/v5sU3UKjIB/uxOhc+TDOnhqffj9pRA== - -"@discordjs/ws@^0.8.3": - version "0.8.3" - resolved "https://registry.npmjs.org/@discordjs/ws/-/ws-0.8.3.tgz" - integrity sha512-hcYtppanjHecbdNyCKQNH2I4RP9UrphDgmRgLYrATEQF1oo4sYSve7ZmGsBEXSzH72MO2tBPdWSThunbxUVk0g== - dependencies: - "@discordjs/collection" "^1.5.1" - "@discordjs/rest" "^1.7.1" - "@discordjs/util" "^0.3.1" - "@sapphire/async-queue" "^1.5.0" - "@types/ws" "^8.5.4" - "@vladfrangu/async_event_emitter" "^2.2.1" - discord-api-types "^0.37.41" - tslib "^2.5.0" - ws "^8.13.0" - -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - -"@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.5.2" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.40.0": - version "8.40.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz" - integrity sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA== - -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@jridgewell/resolve-uri@^3.0.3": - 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== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@opencensus/core@^0.0.8": - version "0.0.8" - resolved "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz" - integrity sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ== - dependencies: - continuation-local-storage "^3.2.1" - log-driver "^1.2.7" - semver "^5.5.0" - shimmer "^1.2.0" - uuid "^3.2.1" - -"@opencensus/core@0.0.9": - version "0.0.9" - resolved "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz" - integrity sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q== - dependencies: - continuation-local-storage "^3.2.1" - log-driver "^1.2.7" - semver "^5.5.0" - shimmer "^1.2.0" - uuid "^3.2.1" - -"@opencensus/propagation-b3@0.0.8": - version "0.0.8" - resolved "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz" - integrity sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A== - dependencies: - "@opencensus/core" "^0.0.8" - uuid "^3.2.1" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@pm2/agent@~2.0.0": - version "2.0.1" - resolved "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.1.tgz" - integrity sha512-QKHMm6yexcvdDfcNE7PL9D6uEjoQPGRi+8dh+rc4Hwtbpsbh5IAvZbz3BVGjcd4HaX6pt2xGpOohG7/Y2L4QLw== - dependencies: - async "~3.2.0" - chalk "~3.0.0" - dayjs "~1.8.24" - debug "~4.3.1" - eventemitter2 "~5.0.1" - fast-json-patch "^3.0.0-1" - fclone "~1.0.11" - nssocket "0.6.0" - pm2-axon "~4.0.1" - pm2-axon-rpc "~0.7.0" - proxy-agent "~5.0.0" - semver "~7.2.0" - ws "~7.4.0" - -"@pm2/io@~5.0.0": - version "5.0.0" - resolved "https://registry.npmjs.org/@pm2/io/-/io-5.0.0.tgz" - integrity sha512-3rToDVJaRoob5Lq8+7Q2TZFruoEkdORxwzFpZaqF4bmH6Bkd7kAbdPrI/z8X6k1Meq5rTtScM7MmDgppH6aLlw== - dependencies: - "@opencensus/core" "0.0.9" - "@opencensus/propagation-b3" "0.0.8" - async "~2.6.1" - debug "~4.3.1" - eventemitter2 "^6.3.1" - require-in-the-middle "^5.0.0" - semver "6.3.0" - shimmer "^1.2.0" - signal-exit "^3.0.3" - tslib "1.9.3" - -"@pm2/js-api@~0.6.7": - version "0.6.7" - resolved "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz" - integrity sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw== - dependencies: - async "^2.6.3" - axios "^0.21.0" - debug "~4.3.1" - eventemitter2 "^6.3.1" - ws "^7.0.0" - -"@pm2/pm2-version-check@latest": - version "1.0.4" - resolved "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz" - integrity sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA== - dependencies: - debug "^4.3.1" - -"@prisma/debug@4.14.0": - version "4.14.0" - resolved "https://registry.npmjs.org/@prisma/debug/-/debug-4.14.0.tgz" - integrity sha512-K3yFVN3BZRCoSwit0uFAXSFlt3lz6iKJqPPZMuEH6n7zCFRBoQJhDT+QiMIfMdf6eOy4f0H4yK0KFRnx4TJA7Q== - dependencies: - "@types/debug" "4.1.7" - debug "4.3.4" - strip-ansi "6.0.1" - -"@prisma/engines@4.14.0": - version "4.14.0" - resolved "https://registry.npmjs.org/@prisma/engines/-/engines-4.14.0.tgz" - integrity sha512-PDNlhP/1vyTgmNyiucGqGCdXIp7HIkkvKO50si3y3PcceeHvqtiKPaH1iJdz63jCWMVMbj2MElSxXPOeBvEVIQ== - -"@prisma/generator-helper@^4.10.1": - version "4.14.0" - resolved "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.14.0.tgz" - integrity sha512-cOULdYfbjxPqdN/ctHKYwqyjcOWaHxS4TuhvK9nCLFAgLh92VAla65aMgbmcqaynh1X6HVlGu0hLbHNACOqKRA== - dependencies: - "@prisma/debug" "4.14.0" - "@types/cross-spawn" "6.0.2" - cross-spawn "7.0.3" - kleur "4.1.5" - -"@sapphire/async-queue@^1.5.0": - version "1.5.0" - resolved "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz" - integrity sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA== - -"@sapphire/shapeshift@^3.8.2": - version "3.8.2" - resolved "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.8.2.tgz" - integrity sha512-NXpnJAsxN3/h9TqQPntOeVWZrpIuucqXI3IWF6tj2fWCoRLCuVK5wx7Dtg7pRrtkYfsMUbDqgKoX26vrC5iYfA== - dependencies: - fast-deep-equal "^3.1.3" - lodash "^4.17.21" - -"@sapphire/snowflake@^3.4.2": - version "3.4.2" - resolved "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.4.2.tgz" - integrity sha512-KJwlv5gkGjs1uFV7/xx81n3tqgBwBJvH94n1xDyH3q+JSmtsMeSleJffarEBfG2yAFeJiFA4BnGOK6FFPHc19g== - -"@tokenizer/token@^0.3.0": - version "0.3.0" - resolved "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz" - integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== - -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== - -"@types/cross-spawn@6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz" - integrity sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw== - dependencies: - "@types/node" "*" - -"@types/debug@4.1.7": - version "4.1.7" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== - dependencies: - "@types/ms" "*" - -"@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/minimatch@*": - version "5.1.2" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - -"@types/ms@*": - version "0.7.31" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/node@*", "@types/node@^18.16.2": - version "18.16.6" - resolved "https://registry.npmjs.org/@types/node/-/node-18.16.6.tgz" - integrity sha512-N7KINmeB8IN3vRR8dhgHEp+YpWvGFcpDoh5XZ8jB5a00AdFKCKEyyGTOPTddUf4JqU1ZKTVxkOxakDvchNVI2Q== - -"@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@types/ws@^8.5.4": - version "8.5.4" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz" - integrity sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg== - dependencies: - "@types/node" "*" - -"@typescript-eslint/eslint-plugin@^5.59.2": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz" - integrity sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.5" - "@typescript-eslint/type-utils" "5.59.5" - "@typescript-eslint/utils" "5.59.5" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.0.0": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz" - integrity sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw== - dependencies: - "@typescript-eslint/scope-manager" "5.59.5" - "@typescript-eslint/types" "5.59.5" - "@typescript-eslint/typescript-estree" "5.59.5" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz" - integrity sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A== - dependencies: - "@typescript-eslint/types" "5.59.5" - "@typescript-eslint/visitor-keys" "5.59.5" - -"@typescript-eslint/type-utils@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz" - integrity sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg== - dependencies: - "@typescript-eslint/typescript-estree" "5.59.5" - "@typescript-eslint/utils" "5.59.5" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz" - integrity sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w== - -"@typescript-eslint/typescript-estree@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz" - integrity sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg== - dependencies: - "@typescript-eslint/types" "5.59.5" - "@typescript-eslint/visitor-keys" "5.59.5" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.5.tgz" - integrity sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.5" - "@typescript-eslint/types" "5.59.5" - "@typescript-eslint/typescript-estree" "5.59.5" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.5": - version "5.59.5" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz" - integrity sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA== - dependencies: - "@typescript-eslint/types" "5.59.5" - eslint-visitor-keys "^3.3.0" - -"@vladfrangu/async_event_emitter@^2.2.1": - version "2.2.1" - resolved "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.1.tgz" - integrity sha512-XtUEAS0m6uVddXW+EImGunLiJZzWNWAZQBoQCUneowrYXPQ6y7c0iWEm/wVYyGpTixTIhUfLRSoYCwojL64htA== - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1, acorn-walk@^8.2.0: - version "8.2.0" - resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.4.1, acorn@^8.7.0, acorn@^8.8.0: - version "8.8.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -agent-base@^6.0.0, agent-base@^6.0.2, agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -amp-message@~0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz" - integrity sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg== - dependencies: - amp "0.3.1" - -amp@~0.3.1, amp@0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz" - integrity sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw== - -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" - integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" - integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== - -array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" - integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== - dependencies: - array-uniq "^1.0.1" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" - integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" - integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== - -ast-types@^0.13.2: - version "0.13.4" - resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz" - integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w== - dependencies: - tslib "^2.0.1" - -async-listener@^0.6.0: - version "0.6.10" - resolved "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz" - integrity sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw== - dependencies: - semver "^5.3.0" - shimmer "^1.1.0" - -async@^2.6.3: - version "2.6.4" - resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" - -async@^3.2.0, async@~3.2.0: - version "3.2.4" - resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - -async@~2.6.1: - version "2.6.4" - resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -axios@^0.21.0: - version "0.21.4" - resolved "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== - dependencies: - follow-redirects "^1.14.0" - -axios@^0.27.2: - version "0.27.2" - resolved "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz" - integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== - dependencies: - follow-redirects "^1.14.9" - form-data "^4.0.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -blessed@0.1.81: - version "0.1.81" - resolved "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz" - integrity sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ== - -bodec@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz" - integrity sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -call-me-maybe@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz" - integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@~3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -charm@~0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz" - integrity sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ== - -chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - 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" - optionalDependencies: - fsevents "~2.3.2" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-tableau@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz" - integrity sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ== - dependencies: - chalk "3.0.0" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" - integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colors@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@2.15.1: - version "2.15.1" - resolved "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -continuation-local-storage@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz" - integrity sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA== - dependencies: - async-listener "^0.6.0" - emitter-listener "^1.1.1" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" - integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -croner@~4.1.92: - version "4.1.97" - resolved "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz" - integrity sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ== - -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-js@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz" - integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== - -culvert@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz" - integrity sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg== - -data-uri-to-buffer@3: - version "3.0.1" - resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz" - integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== - -dayjs@~1.11.5: - version "1.11.7" - resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz" - integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== - -dayjs@~1.8.24: - version "1.8.36" - resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz" - integrity sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw== - -debug@^2.2.0: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^2.3.3: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.6: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@4, debug@4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decode-uri-component@^0.2.0: - version "0.2.2" - resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" - integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== - -deep-is@^0.1.3, deep-is@~0.1.3: - 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== - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" - integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" - integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -degenerator@^3.0.2: - version "3.0.4" - resolved "https://registry.npmjs.org/degenerator/-/degenerator-3.0.4.tgz" - integrity sha512-Z66uPeBfHZAHVmue3HPfyKu2Q0rC2cRxbTOsvmU/po5fvvcx27W4mIu9n0PUlQih4oUYvcG1BsbtVv8x7KDOSw== - dependencies: - ast-types "^0.13.2" - escodegen "^1.8.1" - esprima "^4.0.0" - vm2 "^3.9.17" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz" - integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== - dependencies: - path-type "^3.0.0" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -discord-api-types@^0.37.41: - version "0.37.42" - resolved "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.42.tgz" - integrity sha512-1Huaj9cQ1W7/uryS8MZs/tZemnoKB94thM1cE40lep3rpU3q7WHqkdjN/veX0prTkYlPhcyLd/DeF/pBO8X8oQ== - -discord.js@^14.11.0: - version "14.11.0" - resolved "https://registry.npmjs.org/discord.js/-/discord.js-14.11.0.tgz" - integrity sha512-CkueWYFQ28U38YPR8HgsBR/QT35oPpMbEsTNM30Fs8loBIhnA4s70AwQEoy6JvLcpWWJO7GY0y2BUzZmuBMepQ== - dependencies: - "@discordjs/builders" "^1.6.3" - "@discordjs/collection" "^1.5.1" - "@discordjs/formatters" "^0.3.1" - "@discordjs/rest" "^1.7.1" - "@discordjs/util" "^0.3.1" - "@discordjs/ws" "^0.8.3" - "@sapphire/snowflake" "^3.4.2" - "@types/ws" "^8.5.4" - discord-api-types "^0.37.41" - fast-deep-equal "^3.1.3" - lodash.snakecase "^4.1.1" - tslib "^2.5.0" - undici "^5.22.0" - ws "^8.13.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dotenv@^16.0.3: - version "16.0.3" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz" - integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -emitter-listener@^1.1.1: - version "1.1.2" - resolved "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz" - integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ== - dependencies: - shimmer "^1.2.0" - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -enquirer@2.3.6: - version "2.3.6" - resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escodegen@^1.8.1: - version "1.14.3" - resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== - dependencies: - esprima "^4.0.1" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint@*, "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0": - version "8.40.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz" - integrity sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.40.0" - "@humanwhocodes/config-array" "^0.11.8" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.5.2" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-sdsl "^4.1.4" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== - dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esprima@^4.0.0, esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1, estraverse@^4.2.0: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -eventemitter2@^6.3.1: - version "6.4.9" - resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz" - integrity sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg== - -eventemitter2@~0.4.14: - version "0.4.14" - resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz" - integrity sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ== - -eventemitter2@~5.0.1, eventemitter2@5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz" - integrity sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg== - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" - integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - 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== - -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - 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" - -fast-json-patch@^3.0.0-1: - version "3.1.1" - resolved "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz" - integrity sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -fclone@~1.0.11, fclone@1.0.11: - version "1.0.11" - resolved "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz" - integrity sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw== - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -file-type@^18.3.0: - version "18.3.0" - resolved "https://registry.npmjs.org/file-type/-/file-type-18.3.0.tgz" - integrity sha512-pkPZ5OGIq0TYb37b8bHDLNeQSe1H2KlaQ2ySGpJkkr2KZdaWsO4QhPzHA0mQcsUW2cSqJk+4gM/UyLz/UFbXdQ== - dependencies: - readable-web-to-node-stream "^3.0.2" - strtok3 "^7.0.0" - token-types "^5.0.1" - -file-uri-to-path@2: - version "2.0.0" - resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz" - integrity sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg== - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" - integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -follow-redirects@^1.14.0, follow-redirects@^1.14.9: - version "1.15.2" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" - integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== - -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - -form-data@^4.0.0: - version "4.0.0" - 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" - mime-types "^2.1.12" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" - integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== - dependencies: - map-cache "^0.2.2" - -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -ftp@^0.3.10: - version "0.3.10" - resolved "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz" - integrity sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ== - dependencies: - readable-stream "1.1.x" - xregexp "2.0.0" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -get-uri@3: - version "3.0.2" - resolved "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz" - integrity sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg== - dependencies: - "@tootallnate/once" "1" - data-uri-to-buffer "3" - debug "4" - file-uri-to-path "2" - fs-extra "^8.1.0" - ftp "^0.3.10" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" - integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== - -git-node-fs@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz" - integrity sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ== - -git-sha1@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz" - integrity sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg== - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz" - integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz" - integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== - -glob@^10.2.5: - version "10.2.5" - resolved "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz" - integrity sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.0.3" - minimatch "^9.0.0" - minipass "^5.0.0 || ^6.0.2" - path-scurry "^1.7.0" - -glob@^7.0.5, glob@^7.1.3: - version "7.2.3" - 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" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - 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" - -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - -graceful-fs@^4.1.6, graceful-fs@^4.2.0: - 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== - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" - integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" - integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" - integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" - integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0, https-proxy-agent@5: - version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -iconv-lite@^0.4.4, iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.3: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - 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" - -inherits@^2.0.3, inherits@~2.0.1, inherits@2, inherits@2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.5: - version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -ip@^1.1.5: - version "1.1.8" - resolved "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz" - integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== - -ip@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" - integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-core-module@^2.11.0: - version "2.12.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz" - integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== - dependencies: - has "^1.0.3" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - 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== - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz" - integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" - integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== - dependencies: - kind-of "^3.0.2" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - 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== - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - -isarray@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" - integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -jackspeak@^2.0.3: - version "2.2.0" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz" - integrity sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -js-git@^0.7.8: - version "0.7.8" - resolved "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz" - integrity sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA== - dependencies: - bodec "^0.1.0" - culvert "^0.1.2" - git-sha1 "^0.1.2" - pako "^0.2.5" - -js-sdsl@^4.1.4: - version "4.4.0" - resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz" - integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -json5@^2.2.2: - version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" - integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== - optionalDependencies: - graceful-fs "^4.1.6" - -kind-of@^3.0.2, kind-of@^3.0.3: - version "3.2.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" - integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kleur@4.1.5: - version "4.1.5" - resolved "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz" - integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== - -lazy@~1.0.11: - version "1.0.11" - resolved "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz" - integrity sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.snakecase@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz" - integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== - -lodash@^4.17.14, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-driver@^1.2.7: - version "1.2.7" - resolved "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz" - integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - 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" - -lru-cache@^9.1.1: - version "9.1.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz" - integrity sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A== - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" - integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== - dependencies: - object-visit "^1.0.0" - -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^3.1.10: - version "3.1.10" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - 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" - -minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - 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" - -minimatch@^9.0.0: - version "9.0.0" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz" - integrity sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -"minipass@^5.0.0 || ^6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -module-details-from-path@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz" - integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== - -ms@^2.1.1, ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -mute-stream@~0.0.4: - version "0.0.8" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -needle@2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz" - integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - -netmask@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz" - integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -nssocket@0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz" - integrity sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w== - dependencies: - eventemitter2 "~0.4.14" - lazy "~1.0.11" - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" - integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" - integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== - dependencies: - isobject "^3.0.0" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" - integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== - dependencies: - isobject "^3.0.1" - -once@^1.3.0: - 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" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - 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== - dependencies: - p-limit "^3.0.2" - -pac-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz" - integrity sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - get-uri "3" - http-proxy-agent "^4.0.1" - https-proxy-agent "5" - pac-resolver "^5.0.0" - raw-body "^2.2.0" - socks-proxy-agent "5" - -pac-resolver@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz" - integrity sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q== - dependencies: - degenerator "^3.0.2" - ip "^1.1.5" - netmask "^2.0.2" - -pako@^0.2.5: - version "0.2.9" - resolved "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz" - integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA== - -parent-module@^1.0.0: - 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== - dependencies: - callsites "^3.0.0" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" - integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz" - integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-scurry@^1.7.0: - version "1.9.2" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz" - integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg== - dependencies: - lru-cache "^9.1.1" - minipass "^5.0.0 || ^6.0.2" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -peek-readable@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz" - integrity sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pidusage@^2.0.21: - version "2.0.21" - resolved "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz" - integrity sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA== - dependencies: - safe-buffer "^5.2.1" - -pidusage@~3.0: - version "3.0.2" - resolved "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz" - integrity sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w== - dependencies: - safe-buffer "^5.2.1" - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pm2-axon-rpc@~0.7.0, pm2-axon-rpc@~0.7.1: - version "0.7.1" - resolved "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz" - integrity sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw== - dependencies: - debug "^4.3.1" - -pm2-axon@~4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz" - integrity sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg== - dependencies: - amp "~0.3.1" - amp-message "~0.1.1" - debug "^4.3.1" - escape-string-regexp "^4.0.0" - -pm2-deploy@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz" - integrity sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg== - dependencies: - run-series "^1.1.8" - tv4 "^1.3.0" - -pm2-multimeter@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz" - integrity sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA== - dependencies: - charm "~0.1.1" - -pm2-sysmonit@^1.2.8: - version "1.2.8" - resolved "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz" - integrity sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA== - dependencies: - async "^3.2.0" - debug "^4.3.1" - pidusage "^2.0.21" - systeminformation "^5.7" - tx2 "~1.0.4" - -pm2@^5.3.0: - version "5.3.0" - resolved "https://registry.npmjs.org/pm2/-/pm2-5.3.0.tgz" - integrity sha512-xscmQiAAf6ArVmKhjKTeeN8+Td7ZKnuZFFPw1DGkdFPR/0Iyx+m+1+OpCdf9+HQopX3VPc9/wqPQHqVOfHum9w== - dependencies: - "@pm2/agent" "~2.0.0" - "@pm2/io" "~5.0.0" - "@pm2/js-api" "~0.6.7" - "@pm2/pm2-version-check" latest - async "~3.2.0" - blessed "0.1.81" - chalk "3.0.0" - chokidar "^3.5.3" - cli-tableau "^2.0.0" - commander "2.15.1" - croner "~4.1.92" - dayjs "~1.11.5" - debug "^4.3.1" - enquirer "2.3.6" - eventemitter2 "5.0.1" - fclone "1.0.11" - mkdirp "1.0.4" - needle "2.4.0" - pidusage "~3.0" - pm2-axon "~4.0.1" - pm2-axon-rpc "~0.7.1" - pm2-deploy "~1.0.2" - pm2-multimeter "^0.1.2" - promptly "^2" - semver "^7.2" - source-map-support "0.5.21" - sprintf-js "1.1.2" - vizion "~2.2.1" - yamljs "0.3.0" - optionalDependencies: - pm2-sysmonit "^1.2.8" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" - integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - -prettier@2.8.8: - version "2.8.8" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -prisma-json-types-generator@^2.3.1: - version "2.4.0" - resolved "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-2.4.0.tgz" - integrity sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg== - dependencies: - "@prisma/generator-helper" "^4.10.1" - tslib "^2.5.0" - -prisma@^4.13.0: - version "4.14.0" - resolved "https://registry.npmjs.org/prisma/-/prisma-4.14.0.tgz" - integrity sha512-+5dMl1uxMQb4RepndY6AwR9xi1cDcaGFICu+ws6/Nmgt93mFPNj8tYxSfTdmfg+rkNrUId9rk/Ac2vTgLe/oXA== - dependencies: - "@prisma/engines" "4.14.0" - -promptly@^2: - version "2.2.0" - resolved "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz" - integrity sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA== - dependencies: - read "^1.0.4" - -proxy-agent@~5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz" - integrity sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g== - dependencies: - agent-base "^6.0.0" - debug "4" - http-proxy-agent "^4.0.0" - https-proxy-agent "^5.0.0" - lru-cache "^5.1.1" - pac-proxy-agent "^5.0.0" - proxy-from-env "^1.0.0" - socks-proxy-agent "^5.0.0" - -proxy-from-env@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -raw-body@^2.2.0: - version "2.5.2" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -read@^1.0.4: - version "1.0.7" - resolved "https://registry.npmjs.org/read/-/read-1.0.7.tgz" - integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ== - dependencies: - mute-stream "~0.0.4" - -readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@1.1.x: - version "1.1.14" - 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" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-web-to-node-stream@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz" - integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== - dependencies: - readable-stream "^3.6.0" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - -require-in-the-middle@^5.0.0: - version "5.2.0" - resolved "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz" - integrity sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg== - dependencies: - debug "^4.1.1" - module-details-from-path "^1.0.3" - resolve "^1.22.1" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" - integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== - -resolve@^1.22.1: - version "1.22.2" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== - dependencies: - is-core-module "^2.11.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rimraf@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz" - integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== - dependencies: - glob "^10.2.5" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -run-series@^1.1.8: - version "1.1.9" - resolved "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz" - integrity sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g== - -safe-buffer@^5.2.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" - integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -semver@^5.3.0: - version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@^5.5.0: - version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@^7.2, semver@^7.3.7: - version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -semver@~7.2.0: - version "7.2.3" - resolved "https://registry.npmjs.org/semver/-/semver-7.2.3.tgz" - integrity sha512-utbW9Z7ZxVvwiIWkdOMLOR9G/NFXh2aRucghkVrEMJWuC++r3lCkBC3LwqBinyHzGMAJxY5tn6VakZGHObq5ig== - -semver@6.3.0: - version "6.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shimmer@^1.1.0, shimmer@^1.2.0: - version "1.2.1" - resolved "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz" - integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== - -signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz" - integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -socks-proxy-agent@^5.0.0, socks-proxy-agent@5: - version "5.0.1" - resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz" - integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== - dependencies: - agent-base "^6.0.2" - debug "4" - socks "^2.3.3" - -socks@^2.3.3: - version "2.7.1" - resolved "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== - dependencies: - ip "^2.0.0" - smart-buffer "^4.2.0" - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@0.5.21: - version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -source-map@^0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -sprintf-js@1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" - integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - -string_decoder@^1.1.1: - 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== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1, strip-ansi@6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - 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== - -strtok3@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz" - integrity sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ== - dependencies: - "@tokenizer/token" "^0.3.0" - peek-readable "^5.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - 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== - -systeminformation@^5.7: - version "5.17.12" - resolved "https://registry.npmjs.org/systeminformation/-/systeminformation-5.17.12.tgz" - integrity sha512-I3pfMW2vue53u+X08BNxaJieaHkRoMMKjWetY9lbYJeWFaeWPO6P4FkNc4XOCX8F9vbQ0HqQ25RJoz3U/B7liw== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" - integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" - integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex-range@^5.0.1: - 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== - dependencies: - is-number "^7.0.0" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -token-types@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz" - integrity sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg== - dependencies: - "@tokenizer/token" "^0.3.0" - ieee754 "^1.2.1" - -ts-mixer@^6.0.3: - version "6.0.3" - resolved "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz" - integrity sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ== - -ts-node@^10.9.1: - version "10.9.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - 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" - -tsconfig-paths@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tscpaths@^0.0.9: - version "0.0.9" - resolved "https://registry.npmjs.org/tscpaths/-/tscpaths-0.0.9.tgz" - integrity sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w== - dependencies: - commander "^2.20.0" - globby "^9.2.0" - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.0.1, tslib@^2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== - -tslib@1.9.3: - version "1.9.3" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -tv4@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz" - integrity sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw== - -tx2@~1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/tx2/-/tx2-1.0.5.tgz" - integrity sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg== - dependencies: - json-stringify-safe "^5.0.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - -type-fest@^0.20.2: - 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== - -typescript@^4.9.5, typescript@>=2.7, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": - version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -undici@^5.22.0: - version "5.22.0" - resolved "https://registry.npmjs.org/undici/-/undici-5.22.0.tgz" - integrity sha512-fR9RXCc+6Dxav4P9VV/sp5w3eFiSdOjJYsbtWfd4s5L5C4ogyuVpdKIVHeW0vV1MloM65/f7W45nR9ZxwVdyiA== - dependencies: - busboy "^1.6.0" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" - integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" - integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -uuid@^3.2.1: - version "3.4.0" - resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache-lib@^3.0.1: - 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== - -vizion@~2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz" - integrity sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww== - dependencies: - async "^2.6.3" - git-node-fs "^1.0.0" - ini "^1.3.5" - js-git "^0.7.8" - -vm2@^3.9.17: - version "3.9.19" - resolved "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz" - integrity sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg== - dependencies: - acorn "^8.7.0" - acorn-walk "^8.2.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.4" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz" - integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@^7.0.0, ws@~7.4.0: - version "7.4.6" - resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -ws@^8.13.0: - version "8.13.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== - -xregexp@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz" - integrity sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yamljs@0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz" - integrity sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ== - dependencies: - argparse "^1.0.7" - glob "^7.0.5" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/anify-startup/.gitignore b/anify-startup/.gitignore new file mode 100644 index 0000000..3d75225 --- /dev/null +++ b/anify-startup/.gitignore @@ -0,0 +1,172 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +\*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +\*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +\*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +\*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.cache +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +.cache/ + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp +.cache + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.\* + +# IntelliJ based IDEs +.idea diff --git a/anify-startup/README.md b/anify-startup/README.md new file mode 100644 index 0000000..5becd3a --- /dev/null +++ b/anify-startup/README.md @@ -0,0 +1,15 @@ +# anify-startup + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +``` + +This project was created using `bun init` in bun v1.0.1. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/anify-startup/index.ts b/anify-startup/index.ts new file mode 100644 index 0000000..3d822e0 --- /dev/null +++ b/anify-startup/index.ts @@ -0,0 +1,77 @@ +import { spawn, ChildProcess } from "child_process"; +import { join } from "path"; +import colors from "colors"; + +const directories = [ + join(import.meta.dir, "../anify-frontend"), + join(import.meta.dir, "../anify-backend"), + join(import.meta.dir, "../anify-auth"), +]; + +const runningProcesses = new Map(); + +async function startProcesses() { + for (const directory of directories) { + const childProcess = spawn("pnpm", ["run", "dev"], { + cwd: directory, + detached: true, + }); + + childProcess.stdout.on("data", (data) => { + console.log(colors.green(`[${directory}]`), data.toString()); + }); + + childProcess.stderr.on("data", (data) => { + console.log(colors.red(`[${directory}]`), data.toString()); + }); + + childProcess.unref(); + + runningProcesses.set(directory, childProcess); + } + + colors.green("Started services"); +} + +async function stopProcesses() { + for (const directory of directories) { + console.log(runningProcesses.get(directory)?.pid); + runningProcesses.get(directory)?.kill(); + } + + // Run killall node + await new Promise((resolve, reject) => { + spawn("killall", ["node"]).on("exit", () => { + resolve(true); + }).on("error", (err) => { + reject(err); + }); + }); +} + +startProcesses().then(() => { + console.log(colors.green("Started services")); + // Hang the process + setInterval(() => {}, 1000); +}).catch((err) => { + console.error(colors.red("Error: "), err); +}); + +process.on("beforeExit", async () => { + console.log(colors.red("Stopping services...")); + await stopProcesses().catch((err) => { + console.error(colors.red("Error: "), err); + }); +}); + +process.on("unhandledRejection", (err) => { + console.error(colors.red("Unhandled Promise rejection: "), err); +}); + +process.on("SIGINT", async () => { + console.log(colors.red("Stopping services...")); + await stopProcesses().catch((err) => { + console.error(colors.red("Error: "), err); + }); + process.exit(); +}); \ No newline at end of file diff --git a/anify-startup/package.json b/anify-startup/package.json new file mode 100644 index 0000000..7e0a6a3 --- /dev/null +++ b/anify-startup/package.json @@ -0,0 +1,19 @@ +{ + "name": "anify-startup", + "module": "index.ts", + "type": "module", + "scripts": { + "start": "bun run dist/index.js", + "dev": "bun run index.ts", + "build": "bun build index.ts --outdir ./dist --target node" + }, + "devDependencies": { + "bun-types": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "colors": "^1.4.0" + } +} \ No newline at end of file diff --git a/anify-startup/tsconfig.json b/anify-startup/tsconfig.json new file mode 100644 index 0000000..1449bc3 --- /dev/null +++ b/anify-startup/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "jsx": "preserve", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [ + "bun-types" // add Bun global + ] + } +} diff --git a/package.json b/package.json index ca46283..078a475 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,6 @@ "private": true, "scripts": { "start": "cd anify-manager && npm run dev", - "cli": "cd anify-cli && npm run cli", "install": "cd anify-manager && npm i && cd ../anify-frontend && npm i && cd ../anify-backend && npm i && cd ../anify-auth && npm i", "lint": "cd anify-frontend && npx next lint && cd ../anify-backend && npm run lint && cd ../anify-auth && npm run lint", "build": "npm run build:ts && npm run build:db", From 7e456372bb3549a91a86a3185ca75cea7db6ac91 Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 13 Sep 2023 08:44:20 -0400 Subject: [PATCH 33/77] Squashed commit of the following: commit 65e2afd9fc88bb9c3e097197e7b2c953a0341301 Author: Eltik Date: Fri Sep 8 16:57:09 2023 -0400 Reverted commit --- anify-backend/src/helper/stringSimilarity.ts | 2 +- .../src/mappings/impl/manga/comick.ts | 22 +- .../src/mappings/impl/manga/index.ts | 2 +- anify-backend/src/server/server.ts | 2019 +++++++++++++++++ 4 files changed, 2024 insertions(+), 21 deletions(-) create mode 100644 anify-backend/src/server/server.ts diff --git a/anify-backend/src/helper/stringSimilarity.ts b/anify-backend/src/helper/stringSimilarity.ts index 81bc234..ec3b118 100644 --- a/anify-backend/src/helper/stringSimilarity.ts +++ b/anify-backend/src/helper/stringSimilarity.ts @@ -23,7 +23,7 @@ export function similarity(externalTitle: string, title: string, titleArray: str } // From npm package string-similarity -export function compareTwoStrings(first: string, second: string): number { +export function compareTwoStrings(first, second): number { first = first.replace(/\s+/g, ""); second = second.replace(/\s+/g, ""); diff --git a/anify-backend/src/mappings/impl/manga/comick.ts b/anify-backend/src/mappings/impl/manga/comick.ts index a38a5a0..fef8a9f 100644 --- a/anify-backend/src/mappings/impl/manga/comick.ts +++ b/anify-backend/src/mappings/impl/manga/comick.ts @@ -51,7 +51,7 @@ export default class ComicK extends MangaProvider { const chapters: Chapter[] = []; - data.chapters.map((chapter: ComickChapter) => { + data.chapters.map((chapter) => { let title = ""; if (chapter.vol) { @@ -74,7 +74,7 @@ export default class ComicK extends MangaProvider { chapters.push({ id: chapter.hid, title: title?.trim(), - number: Number(chapter.chap), + number: chapter.chap, updatedAt, }); } @@ -91,7 +91,7 @@ export default class ComicK extends MangaProvider { const pages: Page[] = []; - data.chapter.md_images.map((image: { vol: any; w: number; h: number; b2key: string }, index: number) => { + data.chapter.md_images.map((image, index) => { pages.push({ url: `https://meo.comick.pictures/${image.b2key}?width=${image.w}`, index: index, @@ -167,19 +167,3 @@ interface Comic { lang_name: string; lang_native: string; } - -interface ComickChapter { - id: number; - chap: string; - title: string; - vol: string | null; - lang: string; - created_at: string; - updated_at: string; - up_count: number; - down_count: number; - group_name: any; - hid: string; - identities: any; - md_chapter_groups: { md_groups: { title: string; slug: string } }[]; -} diff --git a/anify-backend/src/mappings/impl/manga/index.ts b/anify-backend/src/mappings/impl/manga/index.ts index d9af44c..5326da1 100644 --- a/anify-backend/src/mappings/impl/manga/index.ts +++ b/anify-backend/src/mappings/impl/manga/index.ts @@ -27,7 +27,7 @@ export default abstract class MangaProvider { return Http.request(url, config, proxyRequest, 0, this.customProxy); } - padNum(number: string, places: number): string { + padNum(number, places): string { // Credit to https://stackoverflow.com/a/10073788 /* * '17' diff --git a/anify-backend/src/server/server.ts b/anify-backend/src/server/server.ts new file mode 100644 index 0000000..8e176ea --- /dev/null +++ b/anify-backend/src/server/server.ts @@ -0,0 +1,2019 @@ +import express from "express"; +import { rateLimit } from "express-rate-limit"; + +import cluster from "node:cluster"; +import os from "node:os"; + +import bodyParser from "body-parser"; +import cors from "cors"; +import cookieParser from "cookie-parser"; +import expressDomainMiddleware from "express-domain-middleware"; + +import Redis from "ioredis"; +import RedisStore from "rate-limit-redis"; + +import colors from "colors"; + +import queues from "../worker"; +import { ANIME_PROVIDERS, Anime, Format, Genres, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, Manga, Type, infoProviders } from "../mapping"; +import { fetchEpisodes } from "../content/impl/episodes"; +import { fetchChapters } from "../content/impl/chapters"; +import { fetchSources } from "../content/impl/sources"; +import { fetchPages } from "../content/impl/pages"; +import { loadSeasonal } from "../lib/season"; +import { loadSkipTimes } from "../lib/skipTimes"; +import { SubType } from "../mapping/impl/anime"; +import { loadEpisodeCovers } from "../content/impl/episodes/episodeCovers"; +import { checkAPIKey, importKeys, masterKey, updateRequests } from "../keys"; +import { fetchSchedule } from "../content/impl/schedule"; +import Database from "../database"; +import { createLoop } from "../tasks"; +import { AnimeInfo, MangaInfo } from "../mapping/impl/information"; +import { env } from "../env"; + +const port = env.PORT; + +const app = express(); +const numCPUs = os.cpus().length; + +const corsOptions = { + origin: "*", + methods: ["POST", "GET", "PATCH", "DELETE", "OPTIONS"], + allowedHeaders: ["Content-Type", "Authorization"], +}; + +let redis = new Redis((env.REDIS_URL as string) || "redis://localhost:6379"); + +const cacheTime = env.REDIS_CACHE_TIME; + +const whitelist = env.API_KEY_WHITELIST; + +app.use(cors(corsOptions)); +app.use(bodyParser.urlencoded({ extended: true })); +app.use(bodyParser.json()); +app.use(expressDomainMiddleware); +app.use(cookieParser()); + +app.get("/", async (request, reply) => { + return reply.json("Documentation can be viewed at https://docs.anify.tv. Join our Discord https://anify.tv/discord for more information."); +}); + +app.use(checkAPIKey); + +if (!env.REDIS_URL) { + console.log(colors.yellow("No Redis URL provided. Caching will be disabled.")); + redis = { + get: async () => null, + set: (): Promise<"OK"> => Promise.resolve("OK"), + on: () => Redis.prototype, + keys: async () => [], + connect: async () => void 0, + call: async () => void 0, + } as any; +} else { + const statsRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 60, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "stats-limiter", + }), + }); + + const genresRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 80, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "stats-limiter", + }), + }); + + const tagsRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 80, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "stats-limiter", + }), + }); + + const searchRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 25, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "search-limiter", + }), + }); + + const scheduleRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 60, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "schedule-limiter", + }), + }); + + const recentRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 60, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "reecnt-limiter", + }), + }); + + const seasonalRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 50, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "seasonal-limiter", + }), + }); + + const infoRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 75, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "info-limiter", + }), + }); + + const mediaRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 75, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "media-limiter", + }), + }); + + const relationsRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 60, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "relations-limiter", + }), + }); + + const episodesRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 40, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "episodes-limiter", + }), + }); + + const chaptersRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 40, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "chapters-limiter", + }), + }); + + const sourcesRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 60, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "sources-limiter", + }), + }); + + const pagesRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 60, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "pages-limiter", + }), + }); + + const episodeCoversRateLimit = rateLimit({ + windowMs: 1 * 60 * 1000, // 1 minute + max: 40, + standardHeaders: true, + legacyHeaders: false, + skip: (request, response) => whitelist.includes(String(request.query.apikey)), + store: new RedisStore({ + // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis + sendCommand: (...args: string[]) => redis.call(...args), + prefix: "episode-covers-limiter", + }), + }); + + app.use("/stats", statsRateLimit); + + app.use("/genres", genresRateLimit); + + app.use("/tags", tagsRateLimit); + + app.use("/search", searchRateLimit); + app.use("/search/:type/:query", searchRateLimit); + + app.use("/search-advanced", searchRateLimit); + + app.use("/seasonal", seasonalRateLimit); + app.use("/seasonal/:type", seasonalRateLimit); + + app.use("/schedule", scheduleRateLimit); + + app.use("/recent", recentRateLimit); + + app.use("/info", infoRateLimit); + app.use("/info/:id", infoRateLimit); + + app.use("/media", mediaRateLimit); + app.use("/media/:providerId/:id", mediaRateLimit); + + app.use("/relations", relationsRateLimit); + app.use("/relations/:id", relationsRateLimit); + + app.use("/episodes", episodesRateLimit); + app.use("/episodes/:id", episodesRateLimit); + app.use("/episodes-mal", episodesRateLimit); + app.use("/episodes-mal/:id", episodesRateLimit); + + app.use("/chapters", chaptersRateLimit); + app.use("/chapters/:id", chaptersRateLimit); + app.use("/chapters-mal", chaptersRateLimit); + app.use("/chapters-mal/:id", chaptersRateLimit); + + app.use("/sources", sourcesRateLimit); + app.use("/sources-mal", sourcesRateLimit); + + app.use("/pages", pagesRateLimit); + app.use("/pages-mal", pagesRateLimit); + + app.use("/episode-covers", episodeCoversRateLimit); + app.use("/episode-covers-mal", episodeCoversRateLimit); +} + +app.get("/providers", async (request, reply) => { + reply.json({ + anime: ANIME_PROVIDERS.map((provider) => { + return { + id: provider.id, + url: provider.url, + formats: provider.formats, + subTypes: provider.subTypes, + headers: provider.headers, + }; + }), + manga: MANGA_PROVIDERS.map((provider) => { + return { + id: provider.id, + url: provider.url, + formats: provider.formats, + }; + }), + info: INFORMATION_PROVIDERS.map((provider) => { + return { + id: provider.id, + url: provider.url, + sharedArea: provider.sharedArea, + priorityArea: provider.priorityArea, + }; + }), + meta: META_PROVIDERS.map((provider) => { + return { + id: provider.id, + url: provider.url, + formats: provider.formats, + }; + }), + }); +}); + +app.get("/stats", async (request, reply) => { + const cached = await redis.get(`stats`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const data = await Database.count(); + + await redis.set(`stats`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +app.post("/stats", async (request, reply) => { + const cached = await redis.get(`stats`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const data = await Database.count(); + + await redis.set(`stats`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +app.get("/genres", async (request, reply) => { + const cached = await redis.get(`genres`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const animeGenres = await Database.fetchAll(Type.ANIME); + const mangaGenres = await Database.fetchAll(Type.MANGA); + + const genres = { + anime: animeGenres.map((anime) => anime.genres).flat(), + manga: mangaGenres.map((manga) => manga.genres).flat(), + }; + + // Remove duplicates + genres.anime = [...new Set(genres.anime)]; + genres.manga = [...new Set(genres.manga)]; + + // Combine genres + const genresList = [...new Set([...genres.anime, ...genres.manga])]; + + // Sort by alphabetical order + genresList.sort(); + + await redis.set(`genres`, JSON.stringify(genresList), "EX", cacheTime); + + return reply.json(genresList); +}); + +app.post("/genres", async (request, reply) => { + const cached = await redis.get(`genres`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const animeGenres = await Database.fetchAll(Type.ANIME); + const mangaGenres = await Database.fetchAll(Type.MANGA); + + const genres = { + anime: animeGenres.map((anime) => anime.genres).flat(), + manga: mangaGenres.map((manga) => manga.genres).flat(), + }; + + // Remove duplicates + genres.anime = [...new Set(genres.anime)]; + genres.manga = [...new Set(genres.manga)]; + + // Combine genres + const genresList = [...new Set([...genres.anime, ...genres.manga])]; + + // Sort by alphabetical order + genresList.sort(); + + await redis.set(`genres`, JSON.stringify(genresList), "EX", cacheTime); + + return reply.json(genresList); +}); + +app.get("/tags", async (request, reply) => { + const cached = await redis.get(`tags`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const animeTags = await Database.fetchAll(Type.ANIME); + const mangaTags = await Database.fetchAll(Type.MANGA); + + const tags = { + anime: animeTags.map((anime) => anime.tags).flat(), + manga: mangaTags.map((manga) => manga.tags).flat(), + }; + + // Remove duplicates + tags.anime = [...new Set(tags.anime)]; + tags.manga = [...new Set(tags.manga)]; + + // Combine genres + const tagsList = [...new Set([...tags.anime, ...tags.manga])]; + + // Sort by alphabetical order + tagsList.sort(); + + await redis.set(`tags`, JSON.stringify(tagsList), "EX", cacheTime); + + return reply.json(tagsList); +}); + +app.post("/tags", async (request, reply) => { + const cached = await redis.get(`tags`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const animeTags = await Database.fetchAll(Type.ANIME); + const mangaTags = await Database.fetchAll(Type.MANGA); + + const tags = { + anime: animeTags.map((anime) => anime.tags).flat(), + manga: mangaTags.map((manga) => manga.tags).flat(), + }; + + // Remove duplicates + tags.anime = [...new Set(tags.anime)]; + tags.manga = [...new Set(tags.manga)]; + + // Combine genres + const tagsList = [...new Set([...tags.anime, ...tags.manga])]; + + // Sort by alphabetical order + tagsList.sort(); + + await redis.set(`tags`, JSON.stringify(tagsList), "EX", cacheTime); + + return reply.json(tagsList); +}); + +/** + * Searches for items of the given type based on the provided query. + * + * @param {String} type - The type of items to search for (anime, manga, novel). + * @param {String} query - The search query. + * + * @throws {400} Invalid type - If the provided type is not valid. + * @throws {400} Invalid query - If the provided query is invalid. + */ +app.get("/search/:type/:query", async (request, reply) => { + const { query } = request.params as { query: string }; + let { type } = request.params as { type: string }; + + const validTypes = ["anime", "manga", "novel"]; + if (!validTypes.includes(type.toLowerCase())) { + return reply.status(400).send({ error: "Invalid type" }); + } + + if (!query || query.length === 0) { + return reply.status(400).send({ error: "Invalid query" }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`search:${originalType}:${query}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.search(query, type.toUpperCase() as Type, formats, 0, 20); + if (existing.length === 0) { + queues.searchQueue.add({ type: type.toUpperCase() as Type, query: query, formats: formats }); + + await redis.set(`search:${originalType}:${query}`, JSON.stringify([]), "EX", cacheTime); + + return reply.json([]); + } else { + await redis.set(`search:${originalType}:${query}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } +}); + +/** + * Searches for items of the given type based on the provided query. + * + * @param {String} type - The type of items to search for (anime, manga, novel). + * @param {String} query - The search query. + * + * @throws {400} Invalid type - If the provided type is not valid. + * @throws {400} Invalid query - If the provided query is invalid. + */ +app.get("/search", async (request, reply) => { + const { query } = request.query as { query: string }; + let { type } = request.query as { type: string }; + + const validTypes = ["anime", "manga", "novel"]; + if (!validTypes.includes(type.toLowerCase())) { + return reply.status(400).send({ error: "Invalid type" }); + } + + if (!query || query.length === 0) { + return reply.status(400).send({ error: "Invalid query" }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`search:${originalType}:${query}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.search(query, type.toUpperCase() as Type, formats, 0, 20); + if (existing.length === 0) { + queues.searchQueue.add({ type: type.toUpperCase() as Type, query: query, formats: formats }); + + await redis.set(`search:${originalType}:${query}`, JSON.stringify([]), "EX", cacheTime); + + return reply.json([]); + } else { + await redis.set(`search:${originalType}:${query}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } +}); + +/** + * Searches for items of the given type based on the provided query. + * + * @param {String} type - The type of items to search for (anime, manga, novel). + * @param {String} query - The search query. + * + * @throws {400} Invalid type - If the provided type is not valid. + * @throws {400} Invalid query - If the provided query is invalid. + */ +app.post("/search", async (request, reply) => { + const { query } = request.body as any; + let { type } = request.body as any; + + const validTypes = ["anime", "manga", "novel"]; + if (!validTypes.includes(type.toLowerCase())) { + return reply.status(400).send({ error: "Invalid type" }); + } + + if (!query || query.length === 0) { + return reply.status(400).send({ error: "Invalid query" }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`search:${originalType}:${query}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.search(query, type.toUpperCase(), formats, 0, 20); + if (existing.length === 0) { + queues.searchQueue.add({ type: type.toUpperCase(), query: query, formats: formats }); + + await redis.set(`search:${originalType}:${query}`, JSON.stringify([]), "EX", cacheTime); + + return reply.json([]); + } else { + await redis.set(`search:${originalType}:${query}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } +}); + +app.get("/search-advanced", async (request, reply) => { + const { query } = request.query as { query: string }; + let { type, page, genres, genresExcluded, tags, tagsExcluded, year } = request.query as { type: string; page: string; genres: string[]; genresExcluded: string[]; tags: string[]; tagsExcluded: string[]; year: string }; + + const validTypes = ["anime", "manga", "novel"]; + if (!validTypes.includes(type.toLowerCase())) { + return reply.status(400).send({ error: "Invalid type" }); + } + + if (!query && String(query).length != 0) { + return reply.status(400).send({ error: "Invalid query" }); + } + + if (!genres) genres = []; + if (!genresExcluded) genresExcluded = []; + if (!tags) tags = []; + if (!tagsExcluded) tagsExcluded = []; + if (!year || isNaN(Number(year))) year = "0"; + + if (!page || isNaN(Number(page))) page = "1"; + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`search-genres:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.searchAdvanced(query, type.toUpperCase() as Type, formats, Number(page), 40, genres as Genres[], genresExcluded as Genres[], Number(year), tags, tagsExcluded); + if (existing.length === 0) { + const newData: Anime[] | Manga[] = []; + + const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).searchAdvanced(query, type.toUpperCase() as Type, formats, Number(page), 2, genres as Genres[], genresExcluded as Genres[], Number(year), tags, tagsExcluded); + for (let i = 0; i < (data ?? []).length; i++) { + const item = data![i]; + const possible = await Database.info((item as any).aniListId); + if (possible) { + let canPush = true; + + for (const genre of genres) { + if (!possible.genres.includes(genre as Genres)) { + canPush = false; + break; + } + } + for (const tag of tags) { + if (!possible.tags.includes(tag)) { + canPush = false; + break; + } + } + for (const genre of genresExcluded) { + if (possible.genres.includes(genre as Genres)) { + canPush = false; + break; + } + } + for (const tag of tagsExcluded) { + if (possible.tags.includes(tag)) { + canPush = false; + break; + } + } + + if (canPush) newData.push(possible as any); + } else { + queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); + } + } + + if (newData.length === 0) { + if (genres.length === 0 && genresExcluded.length === 0 && tags.length === 0 && Number(year) === 0 && tagsExcluded.length === 0) { + const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).search(query, type.toUpperCase() as Type, formats, page, 2); + for (let i = 0; i < (data ?? []).length; i++) { + const item = data![i]; + const possible = await Database.info((item as any).aniListId); + if (possible) newData.push(possible as any); + else queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); + } + + await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); + return reply.json(newData); + } + } + + await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); + return reply.json(newData); + } else { + await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } +}); + +app.post("/search-advanced", async (request, reply) => { + const { query } = request.body as { query: string }; + let { type, page, genres, genresExcluded, tags, tagsExcluded, year } = request.body as { type: string; page: number; genres: string[]; genresExcluded: string[]; tags: string[]; tagsExcluded: string[]; year: number }; + + const validTypes = ["anime", "manga", "novel"]; + if (!validTypes.includes(type.toLowerCase())) { + return reply.status(400).send({ error: "Invalid type" }); + } + + if (!query && String(query).length != 0) { + return reply.status(400).send({ error: "Invalid query" }); + } + + if (!genres) genres = []; + if (!genresExcluded) genresExcluded = []; + if (!tags) tags = []; + if (!tagsExcluded) tagsExcluded = []; + if (!year) year = 0; + + if (!page) page = 1; + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.searchAdvanced(query, type.toUpperCase() as Type, formats, page, 40, genres as Genres[], genresExcluded as Genres[], year, tags, tagsExcluded); + if (existing.length === 0) { + const newData: Anime[] | Manga[] = []; + + const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).searchAdvanced(query, type.toUpperCase() as Type, formats, Number(page), 2, genres as Genres[], genresExcluded as Genres[], Number(year), tags, tagsExcluded); + for (let i = 0; i < (data ?? []).length; i++) { + const item = data![i]; + const possible = await Database.info((item as any).aniListId); + if (possible) { + let canPush = true; + + for (const genre of genres) { + if (!possible.genres.includes(genre as Genres)) { + canPush = false; + break; + } + } + for (const tag of tags) { + if (!possible.tags.includes(tag)) { + canPush = false; + break; + } + } + for (const genre of genresExcluded) { + if (possible.genres.includes(genre as Genres)) { + canPush = false; + break; + } + } + for (const tag of tagsExcluded) { + if (possible.tags.includes(tag)) { + canPush = false; + break; + } + } + + if (canPush) newData.push(possible as any); + } else { + queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); + } + } + + if (newData.length === 0) { + if (genres.length === 0 && genresExcluded.length === 0 && tags.length === 0 && Number(year) === 0 && tagsExcluded.length === 0) { + const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).search(query, type.toUpperCase() as Type, formats, page, 2); + for (let i = 0; i < (data ?? []).length; i++) { + const item = data![i]; + const possible = await Database.info((item as any).aniListId); + if (possible) newData.push(possible as any); + else queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); + } + + await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); + return reply.json(newData); + } + } + + await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); + return reply.json(newData); + } else { + await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } +}); + +/** + * Retrieves seasonal items of the given type. + * + * @param {String} type - The type of items to retrieve (anime, manga, novel). + * + * @throws {400} Invalid type - If the provided type is not valid. + */ +app.get("/seasonal/:type", async (request, reply) => { + let { type } = request.params as { type: string }; + + if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { + return reply.status(400).send({ error: "Invalid type" }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`seasonal:${originalType}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const aniListData = await loadSeasonal({ type: type.toUpperCase() as Type, formats: formats }); + const data = await Database.seasonal(aniListData?.trending, aniListData?.popular, aniListData?.top, aniListData?.seasonal); + + await redis.set(`seasonal:${originalType}`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +/** + * Retrieves seasonal items of the given type. + * + * @param {String} type - The type of items to retrieve (anime, manga, novel). + * + * @throws {400} Invalid type - If the provided type is not valid. + */ +app.get("/seasonal", async (request, reply) => { + let { type } = request.query as { type: string }; + + if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { + return reply.status(400).send({ error: "Invalid type" }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`seasonal:${originalType}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const aniListData = await loadSeasonal({ type: type.toUpperCase() as Type, formats: formats }); + const data = await Database.seasonal(aniListData?.trending, aniListData?.popular, aniListData?.top, aniListData?.seasonal); + + await redis.set(`seasonal:${originalType}`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +/** + * Retrieves seasonal items of the given type. + * + * @param {String} type - The type of items to retrieve (anime, manga, novel). + * + * @throws {400} Invalid type - If the provided type is not valid. + */ +app.post("/seasonal", async (request, reply) => { + let { type } = request.body as { type: string }; + + if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { + return reply.status(400).send({ error: "Invalid type" }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`seasonal:${originalType}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const aniListData = await loadSeasonal({ type: type.toUpperCase() as Type, formats: formats }); + const data = await Database.seasonal(aniListData?.trending, aniListData?.popular, aniListData?.top, aniListData?.seasonal); + + await redis.set(`seasonal:${originalType}`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +app.get("/schedule", async (request, reply) => { + const cached = await redis.get(`schedule`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const data = await fetchSchedule(); + + await redis.set(`schedule`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +app.post("/schedule", async (request, reply) => { + const cached = await redis.get(`schedule`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const data = await fetchSchedule(); + + await redis.set(`schedule`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +app.get("/recent", async (request, reply) => { + let { type, page } = request.query as { type: string; page: string }; + if (!page || isNaN(Number(page))) page = "1"; + + if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { + return reply.status(400).send({ error: "Invalid type" }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`recent:${originalType}:${page}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const data = await Database.recent(type.toUpperCase() as Type, formats, Number(page)); + + await redis.set(`recent:${originalType}:${page}`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +app.post("/recent", async (request, reply) => { + let { type, page } = request.body as { type: string; page: number }; + if (!page) page = 1; + + if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { + return reply.status(400).send({ error: "Invalid type" }); + } + + const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; + + const originalType = type; + + if (type.toLowerCase().includes("novel")) { + type = "manga"; + } + + const cached = await redis.get(`recent:${originalType}:${page}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const data = await Database.recent(type.toUpperCase() as Type, formats, page); + + await redis.set(`recent:${originalType}:${page}`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +/** + * Retrieves information for a media. + * + * @param {String} id - The ID to get information about. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database. + */ +app.get("/info/:id", async (request, reply) => { + const { id } = request.params as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`info:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.info(id); + if (existing) { + await redis.set(`info:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves information for a media. + * + * @param {String} id - The ID to get information about. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database. + */ +app.get("/info", async (request, reply) => { + const { id } = request.query as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`info:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.info(id); + if (existing) { + await redis.set(`info:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves information for a media. + * + * @param {String} id - The ID to get information about. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database. + */ +app.post("/info", async (request, reply) => { + const { id } = request.body as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`info:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.info(id); + if (existing) { + await redis.set(`info:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves information for a media. + * + * @param {String} id - The ID to get information about. + * + * @throws {400} Invalid provider ID - If there is no provided provider ID. + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database. + */ +app.get("/media/:providerId/:id", async (request, reply) => { + const { providerId, id } = request.params as { providerId: string; id: string }; + + if (!providerId || providerId.length === 0) { + return reply.status(400).send({ error: "Invalid provider ID" }); + } + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`media:${providerId}:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.media(providerId, id); + if (existing) { + await redis.set(`media:${providerId}:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves information for a media. + * + * @param {String} id - The ID to get information about. + * + * @throws {400} Invalid provider ID - If there is no provided provider ID. + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database. + */ +app.get("/media", async (request, reply) => { + const { providerId, id } = request.query as { providerId: string; id: string }; + + if (!providerId || providerId.length === 0) { + return reply.status(400).send({ error: "Invalid provider ID" }); + } + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`media:${providerId}:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.media(providerId, id); + if (existing) { + await redis.set(`media:${providerId}:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves information for a media. + * + * @param {String} id - The ID to get information about. + * + * @throws {400} Invalid provider ID - If there is no provided provider ID. + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database. + */ +app.post("/media", async (request, reply) => { + const { providerId, id } = request.body as { providerId: string; id: string }; + + if (!providerId || providerId.length === 0) { + return reply.status(400).send({ error: "Invalid provider ID" }); + } + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`media:${providerId}:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.media(providerId, id); + if (existing) { + await redis.set(`media:${providerId}:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves relations for a media. + * + * @param {String} id - The ID to get information about. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database. + */ +app.get("/relations/:id", async (request, reply) => { + const { id } = request.params as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`relations:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.relations(id); + if (existing) { + await redis.set(`relations:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves relations for a media. + * + * @param {String} id - The ID to get information about. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database. + */ +app.get("/relations", async (request, reply) => { + const { id } = request.query as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`relations:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.relations(id); + if (existing) { + await redis.set(`relations:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves relations for a media. + * + * @param {String} id - The ID to get information about. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database. + */ +app.post("/relations", async (request, reply) => { + const { id } = request.body as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`relations:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await Database.relations(id); + if (existing) { + await redis.set(`relations:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves episodes for a media. + * + * @param {String} id - The ID to get episodes from. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database or there are no episodes. + */ +app.get("/episodes/:id", async (request, reply) => { + const { id } = request.params as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`episodes:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchEpisodes(id); + if (existing) { + await redis.set(`episodes:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves episodes for a media. + * + * @param {String} id - The ID to get episodes from. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database or there are no episodes. + */ +app.get("/episodes", async (request, reply) => { + const { id } = request.query as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`episodes:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchEpisodes(id); + if (existing) { + await redis.set(`episodes:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves episodes for a media. + * + * @param {String} id - The ID to get episodes from. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database or there are no episodes. + */ +app.post("/episodes", async (request, reply) => { + const { id } = request.body as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`episodes:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchEpisodes(id); + if (existing) { + await redis.set(`episodes:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves chapters for a media. + * + * @param {String} id - The ID to get chapters from. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database or there are no chapters. + */ +app.get("/chapters/:id", async (request, reply) => { + const { id } = request.params as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`chapters:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchChapters(id); + if (existing) { + await redis.set(`chapters:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves chapters for a media. + * + * @param {String} id - The ID to get chapters from. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database or there are no chapters. + */ +app.get("/chapters", async (request, reply) => { + const { id } = request.query as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`chapters:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchChapters(id); + if (existing) { + await redis.set(`chapters:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +/** + * Retrieves chapters for a media. + * + * @param {String} id - The ID to get chapters from. + * + * @throws {400} Invalid ID - If there is no provided ID. + * @throws {404} Not found - If the provided ID is not found in the database or there are no chapters. + */ +app.post("/chapters", async (request, reply) => { + const { id } = request.body as { id: string }; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID" }); + } + + const cached = await redis.get(`chapters:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchChapters(id); + if (existing) { + await redis.set(`chapters:${id}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +app.get("/sources", async (request, reply) => { + const { providerId, watchId, episode, id, server } = request.query as any; + let { subType } = request.query as any; + + if (!providerId || providerId.length === 0) { + return reply.status(400).send({ error: "Invalid provider ID." }); + } + + if (!watchId || watchId.length === 0) { + return reply.status(400).send({ error: "Invalid watch ID." }); + } + + if (!episode) { + return reply.status(400).send({ error: "Invalid episode." }); + } + + if (subType && subType.toLowerCase() != SubType.DUB && subType.toLowerCase() != SubType.SUB) { + return reply.status(400).send({ error: "Invalid subtype given." }); + } + + if (!subType) subType = SubType.SUB; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID." }); + } + + const cached = await redis.get(`sources:${providerId}:${watchId}:${server}:${subType}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchSources(providerId, watchId, subType, server); + if (existing) { + const skipTimes = await loadSkipTimes({ toInsert: existing, id: id, episode: episode }).catch((err) => { + return { + intro: { + start: 0, + end: 0, + }, + outro: { + start: 0, + end: 0, + }, + }; + }); + + existing.intro = skipTimes?.intro ?? { + start: 0, + end: 0, + }; + existing.outro = skipTimes?.outro ?? { + start: 0, + end: 0, + }; + + await redis.set(`sources:${providerId}:${watchId}:${server}:${subType}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + + return reply.status(404).send({ error: "Not found", sources: existing }); +}); + +app.post("/sources", async (request, reply) => { + const { providerId, watchId, server, episode, id } = request.body as any; + let { subType } = request.body as any; + + if (!providerId || providerId.length === 0) { + return reply.status(400).send({ error: "Invalid provider ID." }); + } + + if (!watchId || watchId.length === 0) { + return reply.status(400).send({ error: "Invalid watch ID." }); + } + + if (!episode) { + return reply.status(400).send({ error: "Invalid episode." }); + } + + if (subType && subType.toLowerCase() != SubType.DUB && subType.toLowerCase() != SubType.SUB) { + return reply.status(400).send({ error: "Invalid subtype given." }); + } + if (!subType) subType = SubType.SUB; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid ID." }); + } + + const cached = await redis.get(`sources:${providerId}:${watchId}:${server}:${subType}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchSources(providerId, watchId, subType, server); + if (existing) { + const skipTimes = await loadSkipTimes({ toInsert: existing, id: id, episode: episode }).catch((err) => { + return { + intro: { + start: 0, + end: 0, + }, + outro: { + start: 0, + end: 0, + }, + }; + }); + + existing.intro = skipTimes?.intro ?? { + start: 0, + end: 0, + }; + existing.outro = skipTimes?.outro ?? { + start: 0, + end: 0, + }; + + await redis.set(`sources:${providerId}:${watchId}:${server}:${subType}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + + return reply.status(404).send({ error: "Not found", sources: existing }); +}); + +app.get("/skip-times/:id", async (request, reply) => { + const { id } = request.params as any; + + if (!id) { + return reply.status(400).send({ error: "Invalid ID." }); + } + + const cached = await redis.get(`skip-times:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const skipTimes = await Database.findSkipTimes(id).catch((err) => { + return { + intro: { + start: 0, + end: 0, + }, + outro: { + start: 0, + end: 0, + }, + }; + }); + + if (!skipTimes) { + return reply.status(404).send({ error: "Not found." }); + } + + await redis.set(`skip-times:${id}`, JSON.stringify(skipTimes), "EX", cacheTime); + + return reply.json(skipTimes); +}); + +app.get("/skip-times", async (request, reply) => { + const { id } = request.query as any; + + if (!id) { + return reply.status(400).send({ error: "Invalid ID." }); + } + + const cached = await redis.get(`skip-times:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const skipTimes = await Database.findSkipTimes(id).catch((err) => { + return { + intro: { + start: 0, + end: 0, + }, + outro: { + start: 0, + end: 0, + }, + }; + }); + + if (!skipTimes) { + return reply.status(404).send({ error: "Not found." }); + } + + await redis.set(`skip-times:${id}`, JSON.stringify(skipTimes), "EX", cacheTime); + + return reply.json(skipTimes); +}); + +app.post("/skip-times", async (request, reply) => { + const { id } = request.body as any; + + if (!id) { + return reply.status(400).send({ error: "Invalid ID." }); + } + + const cached = await redis.get(`skip-times:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const skipTimes = await Database.findSkipTimes(id).catch((err) => { + return { + intro: { + start: 0, + end: 0, + }, + outro: { + start: 0, + end: 0, + }, + }; + }); + + if (!skipTimes) { + return reply.status(404).send({ error: "Not found." }); + } + + await redis.set(`skip-times:${id}`, JSON.stringify(skipTimes), "EX", cacheTime); + + return reply.json(skipTimes); +}); + +app.get("/pages/:id/:providerId/:readId", async (request, reply) => { + const { id, providerId, readId } = request.params as any; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid AniList ID." }); + } + + if (!providerId || providerId.length === 0) { + return reply.status(400).send({ error: "Invalid provider ID." }); + } + + if (!readId || readId.length === 0) { + return reply.status(400).send({ error: "Invalid read ID." }); + } + + const cached = await redis.get(`pages:${id}:${providerId}:${readId}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchPages(id, providerId, readId); + if (existing) { + await redis.set(`pages:${id}:${providerId}:${readId}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +app.get("/pages", async (request, reply) => { + const { id, providerId, readId } = request.query as any; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid AniList ID." }); + } + + if (!providerId || providerId.length === 0) { + return reply.status(400).send({ error: "Invalid provider ID." }); + } + + if (!readId || readId.length === 0) { + return reply.status(400).send({ error: "Invalid read ID." }); + } + + const cached = await redis.get(`pages:${id}:${providerId}:${readId}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchPages(id, providerId, readId); + if (existing) { + await redis.set(`pages:${id}:${providerId}:${readId}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +app.post("/pages", async (request, reply) => { + const { id, providerId, readId } = request.body as any; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid AniList ID." }); + } + + if (!providerId || providerId.length === 0) { + return reply.status(400).send({ error: "Invalid provider ID." }); + } + + if (!readId || readId.length === 0) { + return reply.status(400).send({ error: "Invalid read ID." }); + } + + const cached = await redis.get(`pages:${id}:${providerId}:${readId}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const existing = await fetchPages(id, providerId, readId); + if (existing) { + await redis.set(`pages:${id}:${providerId}:${readId}`, JSON.stringify(existing), "EX", cacheTime); + + return reply.json(existing); + } + return reply.status(404).send({ error: "Not found" }); +}); + +app.get("/pages-download", async (request, reply) => { + const { id } = request.query as any; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid MixDrop ID." }); + } + + const cached = await redis.get(`pages-download:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const data = await (await fetch(`https://api.mixdrop.co/fileinfo2?email=${env.MIXDROP_EMAIL}&key=${env.MIXDROP_KEY}&ref[]=${id}`)).json(); + + await redis.set(`pages-download:${id}`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +app.post("/pages-download", async (request, reply) => { + const { id } = request.body as any; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid MixDrop ID." }); + } + + const cached = await redis.get(`pages-download:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const data = await (await fetch(`https://api.mixdrop.co/fileinfo2?email=${env.MIXDROP_EMAIL}&key=${env.MIXDROP_KEY}&ref[]=${id}`)).json(); + + await redis.set(`pages-download:${id}`, JSON.stringify(data), "EX", cacheTime); + + return reply.json(data); +}); + +app.get("/episode-covers/:id", async (request, reply) => { + const { id } = request.params as any; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid AniList ID." }); + } + + const cached = await redis.get(`episode-covers:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const anime = await Database.info(id); + if (!anime) { + return reply.status(404).send({ error: "Not found" }); + } + + if (anime.type === Type.ANIME) { + let covers = await loadEpisodeCovers(anime as Anime); + + if (!covers) covers = []; + + await redis.set(`episode-covers:${id}`, JSON.stringify(covers), "EX", cacheTime); + return reply.json(covers); + } else { + return reply.status(400).send({ error: "Type is not anime." }); + } +}); + +app.get("/episode-covers", async (request, reply) => { + const { id } = request.query as any; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid AniList ID." }); + } + + const cached = await redis.get(`episode-covers:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const anime = await Database.info(id); + if (!anime) { + return reply.status(404).send({ error: "Not found" }); + } + + if (anime.type === Type.ANIME) { + let covers = await loadEpisodeCovers(anime as Anime); + + if (!covers) covers = []; + + await redis.set(`episode-covers:${id}`, JSON.stringify(covers), "EX", cacheTime); + return reply.json(covers); + } else { + return reply.status(400).send({ error: "Type is not anime." }); + } +}); + +app.post("/episode-covers", async (request, reply) => { + const { id } = request.body as any; + + if (!id || id.length === 0) { + return reply.status(400).send({ error: "Invalid AniList ID." }); + } + + const cached = await redis.get(`episode-covers:${id}`); + if (cached) { + return reply.json(JSON.parse(cached)); + } + + const anime = await Database.info(id); + if (!anime) { + return reply.status(404).send({ error: "Not found" }); + } + + if (anime.type === Type.ANIME) { + let covers = await loadEpisodeCovers(anime as Anime); + + if (!covers) covers = []; + + await redis.set(`episode-covers:${id}`, JSON.stringify(covers), "EX", cacheTime); + return reply.json(covers); + } else { + return reply.status(400).send({ error: "Type is not anime." }); + } +}); + +// Admin routes +app.get("/update-keys", async (request, reply) => { + if (masterKey === request.query.apikey) { + await updateRequests(); + + return reply.json({ success: "true" }); + } else { + return reply.status(401).json({ error: "Unauthorized" }); + } +}); + +app.get("/key", async (request, reply) => { + const id = request.query.id as string; + + if (!id) return reply.status(400).json({ error: "No ID provided" }); + + const data = await Database.getKeyById(id); + if (!data) return reply.status(404).json({ error: "Key not found" }); + + return reply.json(data); +}); + +app.get("/keys", async (request, reply) => { + if (masterKey === request.query.apikey) { + const data = await Database.fetchAllAPIKeys(); + + return reply.json(data); + } else { + return reply.status(401).json({ error: "Unauthorized" }); + } +}); + +app.get("/assign", async (request, reply) => { + if (masterKey === request.query.apikey) { + const id = request.query.id as string; + const key = request.query.key as string; + + if (!id) return reply.status(400).json({ error: "No ID provided" }); + if (!key) return reply.status(400).json({ error: "No key provided" }); + + const exists = await Database.fetchAPIKey(key); + if (!exists) return reply.status(404).json({ error: "Key not found" }); + + const data = await Database.assignKey(key, id); + if (!data) return reply.status(401).json({ error: "Key already assigned. Please unassign the key first." }); + + return reply.json(data); + } else { + return reply.status(401).json({ error: "Unauthorized" }); + } +}); + +app.get("/unassign", async (request, reply) => { + if (masterKey === request.query.apikey) { + const key = request.query.key as string; + + if (!key) return reply.status(400).json({ error: "No key provided" }); + + const exists = await Database.fetchAPIKey(key); + if (!exists) return reply.status(404).json({ error: "Key not found" }); + + const data = await Database.unassignKey(key); + + return reply.json(data); + } else { + return reply.status(401).json({ error: "Unauthorized" }); + } +}); + +app.get("/delete", async (request, reply) => { + if (masterKey === request.query.apikey) { + const key = request.query.key as string; + + if (!key) return reply.status(400).json({ error: "No key provided" }); + + const data = await Database.deleteKey(key); + + return reply.json(data); + } else { + return reply.status(401).json({ error: "Unauthorized" }); + } +}); + +export const start = async () => { + const masterProcess = () => Array.from(Array(numCPUs)).map(cluster.fork); + const childProcess = () => + app.listen( + { port: port }, + void ((err, address) => { + if (err) { + process.exit(1); + } + }) + ); + + if (cluster.isPrimary) { + console.log(colors.blue(`Server is now listening on ${port}`)); + masterProcess(); + await importKeys(); + await createLoop(); + } else childProcess(); + cluster.on("exit", (worker) => cluster.fork()); +}; From bcf19467fdf87d5520502cea15976298d2d42bf1 Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 13 Sep 2023 08:51:10 -0400 Subject: [PATCH 34/77] Fix merge --- anify-backend/src/helper/stringSimilarity.ts | 2 +- .../src/mappings/impl/manga/comick.ts | 22 +- .../src/mappings/impl/manga/index.ts | 2 +- anify-backend/src/server/server.ts | 2019 ----------------- 4 files changed, 21 insertions(+), 2024 deletions(-) delete mode 100644 anify-backend/src/server/server.ts diff --git a/anify-backend/src/helper/stringSimilarity.ts b/anify-backend/src/helper/stringSimilarity.ts index ec3b118..81bc234 100644 --- a/anify-backend/src/helper/stringSimilarity.ts +++ b/anify-backend/src/helper/stringSimilarity.ts @@ -23,7 +23,7 @@ export function similarity(externalTitle: string, title: string, titleArray: str } // From npm package string-similarity -export function compareTwoStrings(first, second): number { +export function compareTwoStrings(first: string, second: string): number { first = first.replace(/\s+/g, ""); second = second.replace(/\s+/g, ""); diff --git a/anify-backend/src/mappings/impl/manga/comick.ts b/anify-backend/src/mappings/impl/manga/comick.ts index fef8a9f..a38a5a0 100644 --- a/anify-backend/src/mappings/impl/manga/comick.ts +++ b/anify-backend/src/mappings/impl/manga/comick.ts @@ -51,7 +51,7 @@ export default class ComicK extends MangaProvider { const chapters: Chapter[] = []; - data.chapters.map((chapter) => { + data.chapters.map((chapter: ComickChapter) => { let title = ""; if (chapter.vol) { @@ -74,7 +74,7 @@ export default class ComicK extends MangaProvider { chapters.push({ id: chapter.hid, title: title?.trim(), - number: chapter.chap, + number: Number(chapter.chap), updatedAt, }); } @@ -91,7 +91,7 @@ export default class ComicK extends MangaProvider { const pages: Page[] = []; - data.chapter.md_images.map((image, index) => { + data.chapter.md_images.map((image: { vol: any; w: number; h: number; b2key: string }, index: number) => { pages.push({ url: `https://meo.comick.pictures/${image.b2key}?width=${image.w}`, index: index, @@ -167,3 +167,19 @@ interface Comic { lang_name: string; lang_native: string; } + +interface ComickChapter { + id: number; + chap: string; + title: string; + vol: string | null; + lang: string; + created_at: string; + updated_at: string; + up_count: number; + down_count: number; + group_name: any; + hid: string; + identities: any; + md_chapter_groups: { md_groups: { title: string; slug: string } }[]; +} diff --git a/anify-backend/src/mappings/impl/manga/index.ts b/anify-backend/src/mappings/impl/manga/index.ts index 5326da1..d9af44c 100644 --- a/anify-backend/src/mappings/impl/manga/index.ts +++ b/anify-backend/src/mappings/impl/manga/index.ts @@ -27,7 +27,7 @@ export default abstract class MangaProvider { return Http.request(url, config, proxyRequest, 0, this.customProxy); } - padNum(number, places): string { + padNum(number: string, places: number): string { // Credit to https://stackoverflow.com/a/10073788 /* * '17' diff --git a/anify-backend/src/server/server.ts b/anify-backend/src/server/server.ts deleted file mode 100644 index 8e176ea..0000000 --- a/anify-backend/src/server/server.ts +++ /dev/null @@ -1,2019 +0,0 @@ -import express from "express"; -import { rateLimit } from "express-rate-limit"; - -import cluster from "node:cluster"; -import os from "node:os"; - -import bodyParser from "body-parser"; -import cors from "cors"; -import cookieParser from "cookie-parser"; -import expressDomainMiddleware from "express-domain-middleware"; - -import Redis from "ioredis"; -import RedisStore from "rate-limit-redis"; - -import colors from "colors"; - -import queues from "../worker"; -import { ANIME_PROVIDERS, Anime, Format, Genres, INFORMATION_PROVIDERS, MANGA_PROVIDERS, META_PROVIDERS, Manga, Type, infoProviders } from "../mapping"; -import { fetchEpisodes } from "../content/impl/episodes"; -import { fetchChapters } from "../content/impl/chapters"; -import { fetchSources } from "../content/impl/sources"; -import { fetchPages } from "../content/impl/pages"; -import { loadSeasonal } from "../lib/season"; -import { loadSkipTimes } from "../lib/skipTimes"; -import { SubType } from "../mapping/impl/anime"; -import { loadEpisodeCovers } from "../content/impl/episodes/episodeCovers"; -import { checkAPIKey, importKeys, masterKey, updateRequests } from "../keys"; -import { fetchSchedule } from "../content/impl/schedule"; -import Database from "../database"; -import { createLoop } from "../tasks"; -import { AnimeInfo, MangaInfo } from "../mapping/impl/information"; -import { env } from "../env"; - -const port = env.PORT; - -const app = express(); -const numCPUs = os.cpus().length; - -const corsOptions = { - origin: "*", - methods: ["POST", "GET", "PATCH", "DELETE", "OPTIONS"], - allowedHeaders: ["Content-Type", "Authorization"], -}; - -let redis = new Redis((env.REDIS_URL as string) || "redis://localhost:6379"); - -const cacheTime = env.REDIS_CACHE_TIME; - -const whitelist = env.API_KEY_WHITELIST; - -app.use(cors(corsOptions)); -app.use(bodyParser.urlencoded({ extended: true })); -app.use(bodyParser.json()); -app.use(expressDomainMiddleware); -app.use(cookieParser()); - -app.get("/", async (request, reply) => { - return reply.json("Documentation can be viewed at https://docs.anify.tv. Join our Discord https://anify.tv/discord for more information."); -}); - -app.use(checkAPIKey); - -if (!env.REDIS_URL) { - console.log(colors.yellow("No Redis URL provided. Caching will be disabled.")); - redis = { - get: async () => null, - set: (): Promise<"OK"> => Promise.resolve("OK"), - on: () => Redis.prototype, - keys: async () => [], - connect: async () => void 0, - call: async () => void 0, - } as any; -} else { - const statsRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "stats-limiter", - }), - }); - - const genresRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 80, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "stats-limiter", - }), - }); - - const tagsRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 80, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "stats-limiter", - }), - }); - - const searchRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 25, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "search-limiter", - }), - }); - - const scheduleRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "schedule-limiter", - }), - }); - - const recentRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "reecnt-limiter", - }), - }); - - const seasonalRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 50, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "seasonal-limiter", - }), - }); - - const infoRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 75, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "info-limiter", - }), - }); - - const mediaRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 75, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "media-limiter", - }), - }); - - const relationsRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "relations-limiter", - }), - }); - - const episodesRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 40, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "episodes-limiter", - }), - }); - - const chaptersRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 40, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "chapters-limiter", - }), - }); - - const sourcesRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "sources-limiter", - }), - }); - - const pagesRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 60, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "pages-limiter", - }), - }); - - const episodeCoversRateLimit = rateLimit({ - windowMs: 1 * 60 * 1000, // 1 minute - max: 40, - standardHeaders: true, - legacyHeaders: false, - skip: (request, response) => whitelist.includes(String(request.query.apikey)), - store: new RedisStore({ - // @ts-expect-error - Known issue: the `call` function is not present in @types/ioredis - sendCommand: (...args: string[]) => redis.call(...args), - prefix: "episode-covers-limiter", - }), - }); - - app.use("/stats", statsRateLimit); - - app.use("/genres", genresRateLimit); - - app.use("/tags", tagsRateLimit); - - app.use("/search", searchRateLimit); - app.use("/search/:type/:query", searchRateLimit); - - app.use("/search-advanced", searchRateLimit); - - app.use("/seasonal", seasonalRateLimit); - app.use("/seasonal/:type", seasonalRateLimit); - - app.use("/schedule", scheduleRateLimit); - - app.use("/recent", recentRateLimit); - - app.use("/info", infoRateLimit); - app.use("/info/:id", infoRateLimit); - - app.use("/media", mediaRateLimit); - app.use("/media/:providerId/:id", mediaRateLimit); - - app.use("/relations", relationsRateLimit); - app.use("/relations/:id", relationsRateLimit); - - app.use("/episodes", episodesRateLimit); - app.use("/episodes/:id", episodesRateLimit); - app.use("/episodes-mal", episodesRateLimit); - app.use("/episodes-mal/:id", episodesRateLimit); - - app.use("/chapters", chaptersRateLimit); - app.use("/chapters/:id", chaptersRateLimit); - app.use("/chapters-mal", chaptersRateLimit); - app.use("/chapters-mal/:id", chaptersRateLimit); - - app.use("/sources", sourcesRateLimit); - app.use("/sources-mal", sourcesRateLimit); - - app.use("/pages", pagesRateLimit); - app.use("/pages-mal", pagesRateLimit); - - app.use("/episode-covers", episodeCoversRateLimit); - app.use("/episode-covers-mal", episodeCoversRateLimit); -} - -app.get("/providers", async (request, reply) => { - reply.json({ - anime: ANIME_PROVIDERS.map((provider) => { - return { - id: provider.id, - url: provider.url, - formats: provider.formats, - subTypes: provider.subTypes, - headers: provider.headers, - }; - }), - manga: MANGA_PROVIDERS.map((provider) => { - return { - id: provider.id, - url: provider.url, - formats: provider.formats, - }; - }), - info: INFORMATION_PROVIDERS.map((provider) => { - return { - id: provider.id, - url: provider.url, - sharedArea: provider.sharedArea, - priorityArea: provider.priorityArea, - }; - }), - meta: META_PROVIDERS.map((provider) => { - return { - id: provider.id, - url: provider.url, - formats: provider.formats, - }; - }), - }); -}); - -app.get("/stats", async (request, reply) => { - const cached = await redis.get(`stats`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await Database.count(); - - await redis.set(`stats`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.post("/stats", async (request, reply) => { - const cached = await redis.get(`stats`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await Database.count(); - - await redis.set(`stats`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.get("/genres", async (request, reply) => { - const cached = await redis.get(`genres`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const animeGenres = await Database.fetchAll(Type.ANIME); - const mangaGenres = await Database.fetchAll(Type.MANGA); - - const genres = { - anime: animeGenres.map((anime) => anime.genres).flat(), - manga: mangaGenres.map((manga) => manga.genres).flat(), - }; - - // Remove duplicates - genres.anime = [...new Set(genres.anime)]; - genres.manga = [...new Set(genres.manga)]; - - // Combine genres - const genresList = [...new Set([...genres.anime, ...genres.manga])]; - - // Sort by alphabetical order - genresList.sort(); - - await redis.set(`genres`, JSON.stringify(genresList), "EX", cacheTime); - - return reply.json(genresList); -}); - -app.post("/genres", async (request, reply) => { - const cached = await redis.get(`genres`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const animeGenres = await Database.fetchAll(Type.ANIME); - const mangaGenres = await Database.fetchAll(Type.MANGA); - - const genres = { - anime: animeGenres.map((anime) => anime.genres).flat(), - manga: mangaGenres.map((manga) => manga.genres).flat(), - }; - - // Remove duplicates - genres.anime = [...new Set(genres.anime)]; - genres.manga = [...new Set(genres.manga)]; - - // Combine genres - const genresList = [...new Set([...genres.anime, ...genres.manga])]; - - // Sort by alphabetical order - genresList.sort(); - - await redis.set(`genres`, JSON.stringify(genresList), "EX", cacheTime); - - return reply.json(genresList); -}); - -app.get("/tags", async (request, reply) => { - const cached = await redis.get(`tags`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const animeTags = await Database.fetchAll(Type.ANIME); - const mangaTags = await Database.fetchAll(Type.MANGA); - - const tags = { - anime: animeTags.map((anime) => anime.tags).flat(), - manga: mangaTags.map((manga) => manga.tags).flat(), - }; - - // Remove duplicates - tags.anime = [...new Set(tags.anime)]; - tags.manga = [...new Set(tags.manga)]; - - // Combine genres - const tagsList = [...new Set([...tags.anime, ...tags.manga])]; - - // Sort by alphabetical order - tagsList.sort(); - - await redis.set(`tags`, JSON.stringify(tagsList), "EX", cacheTime); - - return reply.json(tagsList); -}); - -app.post("/tags", async (request, reply) => { - const cached = await redis.get(`tags`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const animeTags = await Database.fetchAll(Type.ANIME); - const mangaTags = await Database.fetchAll(Type.MANGA); - - const tags = { - anime: animeTags.map((anime) => anime.tags).flat(), - manga: mangaTags.map((manga) => manga.tags).flat(), - }; - - // Remove duplicates - tags.anime = [...new Set(tags.anime)]; - tags.manga = [...new Set(tags.manga)]; - - // Combine genres - const tagsList = [...new Set([...tags.anime, ...tags.manga])]; - - // Sort by alphabetical order - tagsList.sort(); - - await redis.set(`tags`, JSON.stringify(tagsList), "EX", cacheTime); - - return reply.json(tagsList); -}); - -/** - * Searches for items of the given type based on the provided query. - * - * @param {String} type - The type of items to search for (anime, manga, novel). - * @param {String} query - The search query. - * - * @throws {400} Invalid type - If the provided type is not valid. - * @throws {400} Invalid query - If the provided query is invalid. - */ -app.get("/search/:type/:query", async (request, reply) => { - const { query } = request.params as { query: string }; - let { type } = request.params as { type: string }; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query || query.length === 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search:${originalType}:${query}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.search(query, type.toUpperCase() as Type, formats, 0, 20); - if (existing.length === 0) { - queues.searchQueue.add({ type: type.toUpperCase() as Type, query: query, formats: formats }); - - await redis.set(`search:${originalType}:${query}`, JSON.stringify([]), "EX", cacheTime); - - return reply.json([]); - } else { - await redis.set(`search:${originalType}:${query}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } -}); - -/** - * Searches for items of the given type based on the provided query. - * - * @param {String} type - The type of items to search for (anime, manga, novel). - * @param {String} query - The search query. - * - * @throws {400} Invalid type - If the provided type is not valid. - * @throws {400} Invalid query - If the provided query is invalid. - */ -app.get("/search", async (request, reply) => { - const { query } = request.query as { query: string }; - let { type } = request.query as { type: string }; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query || query.length === 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search:${originalType}:${query}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.search(query, type.toUpperCase() as Type, formats, 0, 20); - if (existing.length === 0) { - queues.searchQueue.add({ type: type.toUpperCase() as Type, query: query, formats: formats }); - - await redis.set(`search:${originalType}:${query}`, JSON.stringify([]), "EX", cacheTime); - - return reply.json([]); - } else { - await redis.set(`search:${originalType}:${query}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } -}); - -/** - * Searches for items of the given type based on the provided query. - * - * @param {String} type - The type of items to search for (anime, manga, novel). - * @param {String} query - The search query. - * - * @throws {400} Invalid type - If the provided type is not valid. - * @throws {400} Invalid query - If the provided query is invalid. - */ -app.post("/search", async (request, reply) => { - const { query } = request.body as any; - let { type } = request.body as any; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query || query.length === 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search:${originalType}:${query}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.search(query, type.toUpperCase(), formats, 0, 20); - if (existing.length === 0) { - queues.searchQueue.add({ type: type.toUpperCase(), query: query, formats: formats }); - - await redis.set(`search:${originalType}:${query}`, JSON.stringify([]), "EX", cacheTime); - - return reply.json([]); - } else { - await redis.set(`search:${originalType}:${query}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } -}); - -app.get("/search-advanced", async (request, reply) => { - const { query } = request.query as { query: string }; - let { type, page, genres, genresExcluded, tags, tagsExcluded, year } = request.query as { type: string; page: string; genres: string[]; genresExcluded: string[]; tags: string[]; tagsExcluded: string[]; year: string }; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query && String(query).length != 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - if (!genres) genres = []; - if (!genresExcluded) genresExcluded = []; - if (!tags) tags = []; - if (!tagsExcluded) tagsExcluded = []; - if (!year || isNaN(Number(year))) year = "0"; - - if (!page || isNaN(Number(page))) page = "1"; - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search-genres:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.searchAdvanced(query, type.toUpperCase() as Type, formats, Number(page), 40, genres as Genres[], genresExcluded as Genres[], Number(year), tags, tagsExcluded); - if (existing.length === 0) { - const newData: Anime[] | Manga[] = []; - - const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).searchAdvanced(query, type.toUpperCase() as Type, formats, Number(page), 2, genres as Genres[], genresExcluded as Genres[], Number(year), tags, tagsExcluded); - for (let i = 0; i < (data ?? []).length; i++) { - const item = data![i]; - const possible = await Database.info((item as any).aniListId); - if (possible) { - let canPush = true; - - for (const genre of genres) { - if (!possible.genres.includes(genre as Genres)) { - canPush = false; - break; - } - } - for (const tag of tags) { - if (!possible.tags.includes(tag)) { - canPush = false; - break; - } - } - for (const genre of genresExcluded) { - if (possible.genres.includes(genre as Genres)) { - canPush = false; - break; - } - } - for (const tag of tagsExcluded) { - if (possible.tags.includes(tag)) { - canPush = false; - break; - } - } - - if (canPush) newData.push(possible as any); - } else { - queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); - } - } - - if (newData.length === 0) { - if (genres.length === 0 && genresExcluded.length === 0 && tags.length === 0 && Number(year) === 0 && tagsExcluded.length === 0) { - const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).search(query, type.toUpperCase() as Type, formats, page, 2); - for (let i = 0; i < (data ?? []).length; i++) { - const item = data![i]; - const possible = await Database.info((item as any).aniListId); - if (possible) newData.push(possible as any); - else queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); - } - - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); - return reply.json(newData); - } - } - - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); - return reply.json(newData); - } else { - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } -}); - -app.post("/search-advanced", async (request, reply) => { - const { query } = request.body as { query: string }; - let { type, page, genres, genresExcluded, tags, tagsExcluded, year } = request.body as { type: string; page: number; genres: string[]; genresExcluded: string[]; tags: string[]; tagsExcluded: string[]; year: number }; - - const validTypes = ["anime", "manga", "novel"]; - if (!validTypes.includes(type.toLowerCase())) { - return reply.status(400).send({ error: "Invalid type" }); - } - - if (!query && String(query).length != 0) { - return reply.status(400).send({ error: "Invalid query" }); - } - - if (!genres) genres = []; - if (!genresExcluded) genresExcluded = []; - if (!tags) tags = []; - if (!tagsExcluded) tagsExcluded = []; - if (!year) year = 0; - - if (!page) page = 1; - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.searchAdvanced(query, type.toUpperCase() as Type, formats, page, 40, genres as Genres[], genresExcluded as Genres[], year, tags, tagsExcluded); - if (existing.length === 0) { - const newData: Anime[] | Manga[] = []; - - const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).searchAdvanced(query, type.toUpperCase() as Type, formats, Number(page), 2, genres as Genres[], genresExcluded as Genres[], Number(year), tags, tagsExcluded); - for (let i = 0; i < (data ?? []).length; i++) { - const item = data![i]; - const possible = await Database.info((item as any).aniListId); - if (possible) { - let canPush = true; - - for (const genre of genres) { - if (!possible.genres.includes(genre as Genres)) { - canPush = false; - break; - } - } - for (const tag of tags) { - if (!possible.tags.includes(tag)) { - canPush = false; - break; - } - } - for (const genre of genresExcluded) { - if (possible.genres.includes(genre as Genres)) { - canPush = false; - break; - } - } - for (const tag of tagsExcluded) { - if (possible.tags.includes(tag)) { - canPush = false; - break; - } - } - - if (canPush) newData.push(possible as any); - } else { - queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); - } - } - - if (newData.length === 0) { - if (genres.length === 0 && genresExcluded.length === 0 && tags.length === 0 && Number(year) === 0 && tagsExcluded.length === 0) { - const data: AnimeInfo[] | MangaInfo[] | undefined = await (infoProviders.anilist as any).search(query, type.toUpperCase() as Type, formats, page, 2); - for (let i = 0; i < (data ?? []).length; i++) { - const item = data![i]; - const possible = await Database.info((item as any).aniListId); - if (possible) newData.push(possible as any); - else queues.mappingQueue.add({ id: (item as any).aniListId, type: type.toUpperCase() as Type }); - } - - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); - return reply.json(newData); - } - } - - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(newData), "EX", cacheTime); - return reply.json(newData); - } else { - await redis.set(`search-advanced:${originalType}:${query}:${JSON.stringify(genres)}:${JSON.stringify(genresExcluded)}:${JSON.stringify(tags)}:${JSON.stringify(tagsExcluded)}:${page}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } -}); - -/** - * Retrieves seasonal items of the given type. - * - * @param {String} type - The type of items to retrieve (anime, manga, novel). - * - * @throws {400} Invalid type - If the provided type is not valid. - */ -app.get("/seasonal/:type", async (request, reply) => { - let { type } = request.params as { type: string }; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`seasonal:${originalType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const aniListData = await loadSeasonal({ type: type.toUpperCase() as Type, formats: formats }); - const data = await Database.seasonal(aniListData?.trending, aniListData?.popular, aniListData?.top, aniListData?.seasonal); - - await redis.set(`seasonal:${originalType}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -/** - * Retrieves seasonal items of the given type. - * - * @param {String} type - The type of items to retrieve (anime, manga, novel). - * - * @throws {400} Invalid type - If the provided type is not valid. - */ -app.get("/seasonal", async (request, reply) => { - let { type } = request.query as { type: string }; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`seasonal:${originalType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const aniListData = await loadSeasonal({ type: type.toUpperCase() as Type, formats: formats }); - const data = await Database.seasonal(aniListData?.trending, aniListData?.popular, aniListData?.top, aniListData?.seasonal); - - await redis.set(`seasonal:${originalType}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -/** - * Retrieves seasonal items of the given type. - * - * @param {String} type - The type of items to retrieve (anime, manga, novel). - * - * @throws {400} Invalid type - If the provided type is not valid. - */ -app.post("/seasonal", async (request, reply) => { - let { type } = request.body as { type: string }; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`seasonal:${originalType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const aniListData = await loadSeasonal({ type: type.toUpperCase() as Type, formats: formats }); - const data = await Database.seasonal(aniListData?.trending, aniListData?.popular, aniListData?.top, aniListData?.seasonal); - - await redis.set(`seasonal:${originalType}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.get("/schedule", async (request, reply) => { - const cached = await redis.get(`schedule`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await fetchSchedule(); - - await redis.set(`schedule`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.post("/schedule", async (request, reply) => { - const cached = await redis.get(`schedule`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await fetchSchedule(); - - await redis.set(`schedule`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.get("/recent", async (request, reply) => { - let { type, page } = request.query as { type: string; page: string }; - if (!page || isNaN(Number(page))) page = "1"; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`recent:${originalType}:${page}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await Database.recent(type.toUpperCase() as Type, formats, Number(page)); - - await redis.set(`recent:${originalType}:${page}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.post("/recent", async (request, reply) => { - let { type, page } = request.body as { type: string; page: number }; - if (!page) page = 1; - - if (!type || (type.toLowerCase() !== "anime" && type.toLowerCase() !== "manga" && type.toLowerCase() !== "novel")) { - return reply.status(400).send({ error: "Invalid type" }); - } - - const formats = type.toLowerCase() === "anime" ? [Format.MOVIE, Format.TV, Format.TV_SHORT, Format.OVA, Format.ONA, Format.OVA] : type.toLowerCase() === "manga" ? [Format.MANGA, Format.ONE_SHOT] : [Format.NOVEL]; - - const originalType = type; - - if (type.toLowerCase().includes("novel")) { - type = "manga"; - } - - const cached = await redis.get(`recent:${originalType}:${page}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await Database.recent(type.toUpperCase() as Type, formats, page); - - await redis.set(`recent:${originalType}:${page}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/info/:id", async (request, reply) => { - const { id } = request.params as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`info:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.info(id); - if (existing) { - await redis.set(`info:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/info", async (request, reply) => { - const { id } = request.query as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`info:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.info(id); - if (existing) { - await redis.set(`info:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.post("/info", async (request, reply) => { - const { id } = request.body as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`info:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.info(id); - if (existing) { - await redis.set(`info:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid provider ID - If there is no provided provider ID. - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/media/:providerId/:id", async (request, reply) => { - const { providerId, id } = request.params as { providerId: string; id: string }; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID" }); - } - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`media:${providerId}:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.media(providerId, id); - if (existing) { - await redis.set(`media:${providerId}:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid provider ID - If there is no provided provider ID. - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/media", async (request, reply) => { - const { providerId, id } = request.query as { providerId: string; id: string }; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID" }); - } - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`media:${providerId}:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.media(providerId, id); - if (existing) { - await redis.set(`media:${providerId}:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves information for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid provider ID - If there is no provided provider ID. - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.post("/media", async (request, reply) => { - const { providerId, id } = request.body as { providerId: string; id: string }; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID" }); - } - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`media:${providerId}:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.media(providerId, id); - if (existing) { - await redis.set(`media:${providerId}:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves relations for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/relations/:id", async (request, reply) => { - const { id } = request.params as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`relations:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.relations(id); - if (existing) { - await redis.set(`relations:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves relations for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.get("/relations", async (request, reply) => { - const { id } = request.query as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`relations:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.relations(id); - if (existing) { - await redis.set(`relations:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves relations for a media. - * - * @param {String} id - The ID to get information about. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database. - */ -app.post("/relations", async (request, reply) => { - const { id } = request.body as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`relations:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await Database.relations(id); - if (existing) { - await redis.set(`relations:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves episodes for a media. - * - * @param {String} id - The ID to get episodes from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no episodes. - */ -app.get("/episodes/:id", async (request, reply) => { - const { id } = request.params as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`episodes:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchEpisodes(id); - if (existing) { - await redis.set(`episodes:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves episodes for a media. - * - * @param {String} id - The ID to get episodes from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no episodes. - */ -app.get("/episodes", async (request, reply) => { - const { id } = request.query as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`episodes:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchEpisodes(id); - if (existing) { - await redis.set(`episodes:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves episodes for a media. - * - * @param {String} id - The ID to get episodes from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no episodes. - */ -app.post("/episodes", async (request, reply) => { - const { id } = request.body as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`episodes:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchEpisodes(id); - if (existing) { - await redis.set(`episodes:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves chapters for a media. - * - * @param {String} id - The ID to get chapters from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no chapters. - */ -app.get("/chapters/:id", async (request, reply) => { - const { id } = request.params as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`chapters:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchChapters(id); - if (existing) { - await redis.set(`chapters:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves chapters for a media. - * - * @param {String} id - The ID to get chapters from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no chapters. - */ -app.get("/chapters", async (request, reply) => { - const { id } = request.query as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`chapters:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchChapters(id); - if (existing) { - await redis.set(`chapters:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -/** - * Retrieves chapters for a media. - * - * @param {String} id - The ID to get chapters from. - * - * @throws {400} Invalid ID - If there is no provided ID. - * @throws {404} Not found - If the provided ID is not found in the database or there are no chapters. - */ -app.post("/chapters", async (request, reply) => { - const { id } = request.body as { id: string }; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID" }); - } - - const cached = await redis.get(`chapters:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchChapters(id); - if (existing) { - await redis.set(`chapters:${id}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -app.get("/sources", async (request, reply) => { - const { providerId, watchId, episode, id, server } = request.query as any; - let { subType } = request.query as any; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!watchId || watchId.length === 0) { - return reply.status(400).send({ error: "Invalid watch ID." }); - } - - if (!episode) { - return reply.status(400).send({ error: "Invalid episode." }); - } - - if (subType && subType.toLowerCase() != SubType.DUB && subType.toLowerCase() != SubType.SUB) { - return reply.status(400).send({ error: "Invalid subtype given." }); - } - - if (!subType) subType = SubType.SUB; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`sources:${providerId}:${watchId}:${server}:${subType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchSources(providerId, watchId, subType, server); - if (existing) { - const skipTimes = await loadSkipTimes({ toInsert: existing, id: id, episode: episode }).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - existing.intro = skipTimes?.intro ?? { - start: 0, - end: 0, - }; - existing.outro = skipTimes?.outro ?? { - start: 0, - end: 0, - }; - - await redis.set(`sources:${providerId}:${watchId}:${server}:${subType}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - - return reply.status(404).send({ error: "Not found", sources: existing }); -}); - -app.post("/sources", async (request, reply) => { - const { providerId, watchId, server, episode, id } = request.body as any; - let { subType } = request.body as any; - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!watchId || watchId.length === 0) { - return reply.status(400).send({ error: "Invalid watch ID." }); - } - - if (!episode) { - return reply.status(400).send({ error: "Invalid episode." }); - } - - if (subType && subType.toLowerCase() != SubType.DUB && subType.toLowerCase() != SubType.SUB) { - return reply.status(400).send({ error: "Invalid subtype given." }); - } - if (!subType) subType = SubType.SUB; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`sources:${providerId}:${watchId}:${server}:${subType}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchSources(providerId, watchId, subType, server); - if (existing) { - const skipTimes = await loadSkipTimes({ toInsert: existing, id: id, episode: episode }).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - existing.intro = skipTimes?.intro ?? { - start: 0, - end: 0, - }; - existing.outro = skipTimes?.outro ?? { - start: 0, - end: 0, - }; - - await redis.set(`sources:${providerId}:${watchId}:${server}:${subType}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - - return reply.status(404).send({ error: "Not found", sources: existing }); -}); - -app.get("/skip-times/:id", async (request, reply) => { - const { id } = request.params as any; - - if (!id) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`skip-times:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const skipTimes = await Database.findSkipTimes(id).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - if (!skipTimes) { - return reply.status(404).send({ error: "Not found." }); - } - - await redis.set(`skip-times:${id}`, JSON.stringify(skipTimes), "EX", cacheTime); - - return reply.json(skipTimes); -}); - -app.get("/skip-times", async (request, reply) => { - const { id } = request.query as any; - - if (!id) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`skip-times:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const skipTimes = await Database.findSkipTimes(id).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - if (!skipTimes) { - return reply.status(404).send({ error: "Not found." }); - } - - await redis.set(`skip-times:${id}`, JSON.stringify(skipTimes), "EX", cacheTime); - - return reply.json(skipTimes); -}); - -app.post("/skip-times", async (request, reply) => { - const { id } = request.body as any; - - if (!id) { - return reply.status(400).send({ error: "Invalid ID." }); - } - - const cached = await redis.get(`skip-times:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const skipTimes = await Database.findSkipTimes(id).catch((err) => { - return { - intro: { - start: 0, - end: 0, - }, - outro: { - start: 0, - end: 0, - }, - }; - }); - - if (!skipTimes) { - return reply.status(404).send({ error: "Not found." }); - } - - await redis.set(`skip-times:${id}`, JSON.stringify(skipTimes), "EX", cacheTime); - - return reply.json(skipTimes); -}); - -app.get("/pages/:id/:providerId/:readId", async (request, reply) => { - const { id, providerId, readId } = request.params as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!readId || readId.length === 0) { - return reply.status(400).send({ error: "Invalid read ID." }); - } - - const cached = await redis.get(`pages:${id}:${providerId}:${readId}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchPages(id, providerId, readId); - if (existing) { - await redis.set(`pages:${id}:${providerId}:${readId}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -app.get("/pages", async (request, reply) => { - const { id, providerId, readId } = request.query as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!readId || readId.length === 0) { - return reply.status(400).send({ error: "Invalid read ID." }); - } - - const cached = await redis.get(`pages:${id}:${providerId}:${readId}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchPages(id, providerId, readId); - if (existing) { - await redis.set(`pages:${id}:${providerId}:${readId}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -app.post("/pages", async (request, reply) => { - const { id, providerId, readId } = request.body as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - if (!providerId || providerId.length === 0) { - return reply.status(400).send({ error: "Invalid provider ID." }); - } - - if (!readId || readId.length === 0) { - return reply.status(400).send({ error: "Invalid read ID." }); - } - - const cached = await redis.get(`pages:${id}:${providerId}:${readId}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const existing = await fetchPages(id, providerId, readId); - if (existing) { - await redis.set(`pages:${id}:${providerId}:${readId}`, JSON.stringify(existing), "EX", cacheTime); - - return reply.json(existing); - } - return reply.status(404).send({ error: "Not found" }); -}); - -app.get("/pages-download", async (request, reply) => { - const { id } = request.query as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid MixDrop ID." }); - } - - const cached = await redis.get(`pages-download:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await (await fetch(`https://api.mixdrop.co/fileinfo2?email=${env.MIXDROP_EMAIL}&key=${env.MIXDROP_KEY}&ref[]=${id}`)).json(); - - await redis.set(`pages-download:${id}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.post("/pages-download", async (request, reply) => { - const { id } = request.body as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid MixDrop ID." }); - } - - const cached = await redis.get(`pages-download:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const data = await (await fetch(`https://api.mixdrop.co/fileinfo2?email=${env.MIXDROP_EMAIL}&key=${env.MIXDROP_KEY}&ref[]=${id}`)).json(); - - await redis.set(`pages-download:${id}`, JSON.stringify(data), "EX", cacheTime); - - return reply.json(data); -}); - -app.get("/episode-covers/:id", async (request, reply) => { - const { id } = request.params as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - const cached = await redis.get(`episode-covers:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const anime = await Database.info(id); - if (!anime) { - return reply.status(404).send({ error: "Not found" }); - } - - if (anime.type === Type.ANIME) { - let covers = await loadEpisodeCovers(anime as Anime); - - if (!covers) covers = []; - - await redis.set(`episode-covers:${id}`, JSON.stringify(covers), "EX", cacheTime); - return reply.json(covers); - } else { - return reply.status(400).send({ error: "Type is not anime." }); - } -}); - -app.get("/episode-covers", async (request, reply) => { - const { id } = request.query as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - const cached = await redis.get(`episode-covers:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const anime = await Database.info(id); - if (!anime) { - return reply.status(404).send({ error: "Not found" }); - } - - if (anime.type === Type.ANIME) { - let covers = await loadEpisodeCovers(anime as Anime); - - if (!covers) covers = []; - - await redis.set(`episode-covers:${id}`, JSON.stringify(covers), "EX", cacheTime); - return reply.json(covers); - } else { - return reply.status(400).send({ error: "Type is not anime." }); - } -}); - -app.post("/episode-covers", async (request, reply) => { - const { id } = request.body as any; - - if (!id || id.length === 0) { - return reply.status(400).send({ error: "Invalid AniList ID." }); - } - - const cached = await redis.get(`episode-covers:${id}`); - if (cached) { - return reply.json(JSON.parse(cached)); - } - - const anime = await Database.info(id); - if (!anime) { - return reply.status(404).send({ error: "Not found" }); - } - - if (anime.type === Type.ANIME) { - let covers = await loadEpisodeCovers(anime as Anime); - - if (!covers) covers = []; - - await redis.set(`episode-covers:${id}`, JSON.stringify(covers), "EX", cacheTime); - return reply.json(covers); - } else { - return reply.status(400).send({ error: "Type is not anime." }); - } -}); - -// Admin routes -app.get("/update-keys", async (request, reply) => { - if (masterKey === request.query.apikey) { - await updateRequests(); - - return reply.json({ success: "true" }); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -app.get("/key", async (request, reply) => { - const id = request.query.id as string; - - if (!id) return reply.status(400).json({ error: "No ID provided" }); - - const data = await Database.getKeyById(id); - if (!data) return reply.status(404).json({ error: "Key not found" }); - - return reply.json(data); -}); - -app.get("/keys", async (request, reply) => { - if (masterKey === request.query.apikey) { - const data = await Database.fetchAllAPIKeys(); - - return reply.json(data); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -app.get("/assign", async (request, reply) => { - if (masterKey === request.query.apikey) { - const id = request.query.id as string; - const key = request.query.key as string; - - if (!id) return reply.status(400).json({ error: "No ID provided" }); - if (!key) return reply.status(400).json({ error: "No key provided" }); - - const exists = await Database.fetchAPIKey(key); - if (!exists) return reply.status(404).json({ error: "Key not found" }); - - const data = await Database.assignKey(key, id); - if (!data) return reply.status(401).json({ error: "Key already assigned. Please unassign the key first." }); - - return reply.json(data); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -app.get("/unassign", async (request, reply) => { - if (masterKey === request.query.apikey) { - const key = request.query.key as string; - - if (!key) return reply.status(400).json({ error: "No key provided" }); - - const exists = await Database.fetchAPIKey(key); - if (!exists) return reply.status(404).json({ error: "Key not found" }); - - const data = await Database.unassignKey(key); - - return reply.json(data); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -app.get("/delete", async (request, reply) => { - if (masterKey === request.query.apikey) { - const key = request.query.key as string; - - if (!key) return reply.status(400).json({ error: "No key provided" }); - - const data = await Database.deleteKey(key); - - return reply.json(data); - } else { - return reply.status(401).json({ error: "Unauthorized" }); - } -}); - -export const start = async () => { - const masterProcess = () => Array.from(Array(numCPUs)).map(cluster.fork); - const childProcess = () => - app.listen( - { port: port }, - void ((err, address) => { - if (err) { - process.exit(1); - } - }) - ); - - if (cluster.isPrimary) { - console.log(colors.blue(`Server is now listening on ${port}`)); - masterProcess(); - await importKeys(); - await createLoop(); - } else childProcess(); - cluster.on("exit", (worker) => cluster.fork()); -}; From f5f2d157c3aa692d57a65e34ee042c32ab4455d7 Mon Sep 17 00:00:00 2001 From: Eltik Date: Wed, 13 Sep 2023 08:56:06 -0400 Subject: [PATCH 35/77] Update manager --- anify-manager/.gitignore | 1 + anify-manager/src/config.ts | 2 +- anify-startup/index.ts | 4 ++++ package.json | 11 +++++------ 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/anify-manager/.gitignore b/anify-manager/.gitignore index f81d56e..a194027 100644 --- a/anify-manager/.gitignore +++ b/anify-manager/.gitignore @@ -167,3 +167,4 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.\* +/builds \ No newline at end of file diff --git a/anify-manager/src/config.ts b/anify-manager/src/config.ts index bbdd7f2..c954752 100644 --- a/anify-manager/src/config.ts +++ b/anify-manager/src/config.ts @@ -18,7 +18,7 @@ export const runCommands: { export const repositories = [ { - url: "https://github.com/Eltik/Anify/tree/bun", + url: "https://github.com/concumin/Anify", name: "anify", }, ]; diff --git a/anify-startup/index.ts b/anify-startup/index.ts index 3d822e0..d3f5f68 100644 --- a/anify-startup/index.ts +++ b/anify-startup/index.ts @@ -39,6 +39,9 @@ async function stopProcesses() { runningProcesses.get(directory)?.kill(); } + runningProcesses.clear(); + + /* // Run killall node await new Promise((resolve, reject) => { spawn("killall", ["node"]).on("exit", () => { @@ -47,6 +50,7 @@ async function stopProcesses() { reject(err); }); }); + */ } startProcesses().then(() => { diff --git a/package.json b/package.json index 078a475..91160d4 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,10 @@ "description": "The best Japanese media web application.", "private": true, "scripts": { - "start": "cd anify-manager && npm run dev", - "install": "cd anify-manager && npm i && cd ../anify-frontend && npm i && cd ../anify-backend && npm i && cd ../anify-auth && npm i", - "lint": "cd anify-frontend && npx next lint && cd ../anify-backend && npm run lint && cd ../anify-auth && npm run lint", - "build": "npm run build:ts && npm run build:db", - "build:ts": "cd anify-manager && npm run build:ts && cd ../anify-backend && npm run build:ts && cd ../anify-frontend && npm run build && cd ../anify-auth && npm run build:ts", - "build:db": "cd anify-frontend && npm run build:db && cd ../anify-backend && npm run build:db && cd ../anify-auth && npm run build:db" + "start": "cd anify-startup && bun run dev", + "install": "cd anify-manager && bun install && cd ../anify-frontend && npm i && cd ../anify-backend && bun install && cd ../anify-auth && npm i", + "lint": "cd anify-frontend && npx next lint && cd ../anify-backend && bun run lint && cd ../anify-auth && bun run lint", + "build": "npm run build:ts", + "build:ts": "cd anify-manager && tsc && bun run build && cd ../anify-backend && tsc && bun run build && cd ../anify-frontend && npm run build && cd ../anify-auth && npm run build:ts" } } From 11136f85cdaf89c15a5551fd705935f46c33951b Mon Sep 17 00:00:00 2001 From: Eltik Date: Thu, 14 Sep 2023 13:53:28 -0400 Subject: [PATCH 36/77] Update auth and manager --- anify-auth/.env.example | 25 - anify-auth/.gitignore | 197 +- anify-auth/README.md | 17 +- anify-auth/db.sqlite | Bin 0 -> 57344 bytes anify-auth/package-lock.json | 6840 ----------------- anify-auth/package.json | 82 +- anify-auth/pnpm-lock.yaml | 5819 -------------- anify-auth/prisma/schema.prisma | 84 - anify-auth/src/database/impl/get.ts | 8 + anify-auth/src/database/impl/insert.ts | 29 + anify-auth/src/database/impl/login.ts | 16 + anify-auth/src/database/impl/update.ts | 17 + anify-auth/src/database/index.ts | 97 + anify-auth/src/env.ts | 11 +- anify-auth/src/helper/index.ts | 12 +- anify-auth/src/index.ts | 158 +- anify-auth/src/lib/impl/database.ts | 151 - anify-auth/src/lib/impl/sync.ts | 126 - anify-auth/src/lib/index.ts | 0 anify-auth/src/lib/types.ts | 269 - anify-auth/src/providers/impl/anilist.ts | 18 +- anify-auth/src/providers/impl/index.ts | 198 +- anify-auth/src/providers/impl/mal.ts | 31 +- anify-auth/src/providers/index.ts | 15 +- anify-auth/src/scripts/buildDb.ts | 21 - anify-auth/src/scripts/checkEnv.ts | 20 - anify-auth/src/scripts/clear.ts | 15 - anify-auth/src/server/impl/createUser.ts | 43 + anify-auth/src/server/impl/login.ts | 37 + anify-auth/src/server/impl/providers.ts | 55 + anify-auth/src/server/impl/updateUser.ts | 41 + anify-auth/src/server/impl/user.ts | 45 + anify-auth/src/server/index.ts | 68 + anify-auth/src/types/index.ts | 5 + anify-auth/tsconfig.json | 51 +- anify-auth/yarn.lock | 3864 ---------- anify-backend/db.sqlite | Bin 5808128 -> 5808128 bytes anify-backend/src/index.ts | 16 +- anify-frontend/src/pages/login.tsx | 2 +- anify-manager/package.json | 3 +- anify-manager/src/config.ts | 2 +- anify-manager/src/discord/client.ts | 6 +- .../src/discord/commands/anify/pull.ts | 2 +- .../src/discord/commands/anify/run.ts | 3 +- .../src/discord/commands/anify/stop.ts | 59 + .../src/discord/commands/anify/update.ts | 74 + anify-manager/src/utils/pm2/build.ts | 2 +- anify-manager/src/utils/pm2/index.ts | 2 - anify-manager/src/utils/pm2/init.ts | 17 + anify-manager/src/utils/pm2/kill.ts | 14 +- anify-manager/src/utils/pm2/list.ts | 19 +- anify-manager/src/utils/pm2/run.ts | 46 +- anify-manager/src/utils/pm2/update.ts | 5 +- anify-manager/tsconfig.json | 6 +- 54 files changed, 1057 insertions(+), 17706 deletions(-) delete mode 100644 anify-auth/.env.example create mode 100644 anify-auth/db.sqlite delete mode 100644 anify-auth/package-lock.json delete mode 100644 anify-auth/pnpm-lock.yaml delete mode 100644 anify-auth/prisma/schema.prisma create mode 100644 anify-auth/src/database/impl/get.ts create mode 100644 anify-auth/src/database/impl/insert.ts create mode 100644 anify-auth/src/database/impl/login.ts create mode 100644 anify-auth/src/database/impl/update.ts create mode 100644 anify-auth/src/database/index.ts delete mode 100644 anify-auth/src/lib/impl/database.ts delete mode 100644 anify-auth/src/lib/impl/sync.ts delete mode 100644 anify-auth/src/lib/index.ts delete mode 100644 anify-auth/src/lib/types.ts delete mode 100644 anify-auth/src/scripts/buildDb.ts delete mode 100644 anify-auth/src/scripts/checkEnv.ts delete mode 100644 anify-auth/src/scripts/clear.ts create mode 100644 anify-auth/src/server/impl/createUser.ts create mode 100644 anify-auth/src/server/impl/login.ts create mode 100644 anify-auth/src/server/impl/providers.ts create mode 100644 anify-auth/src/server/impl/updateUser.ts create mode 100644 anify-auth/src/server/impl/user.ts create mode 100644 anify-auth/src/server/index.ts create mode 100644 anify-auth/src/types/index.ts delete mode 100644 anify-auth/yarn.lock create mode 100644 anify-manager/src/discord/commands/anify/stop.ts create mode 100644 anify-manager/src/discord/commands/anify/update.ts create mode 100644 anify-manager/src/utils/pm2/init.ts diff --git a/anify-auth/.env.example b/anify-auth/.env.example deleted file mode 100644 index be71c28..0000000 --- a/anify-auth/.env.example +++ /dev/null @@ -1,25 +0,0 @@ -# What port to listen to -PORT="3606" -# Public URL -PUBLIC_URL="http://localhost:3606" -FRONTEND_URL="http://localhost:3000" -# Backend URL -BACKEND_URL="http://localhost:3060" -# API Key -BACKEND_KEY="" -# SQLite database URL -DATABASE_URL="file:./db.sqlite" -# Redis URL -REDIS_URL="redis://localhost:6379" -# How long to cache redis data -REDIS_CACHE_TIME="18000" - -# Provider API information -ANILIST_CLIENT_ID="" -ANILIST_CLIENT_SECRET="" - -MAL_CLIENT_ID="" -MAL_CLIENT_SECRET="" - -SIMKL_CLIENT_ID="" -SIMKL_CLIENT_SECRET="" \ No newline at end of file diff --git a/anify-auth/.gitignore b/anify-auth/.gitignore index bc2cc3c..3d75225 100644 --- a/anify-auth/.gitignore +++ b/anify-auth/.gitignore @@ -1,33 +1,172 @@ -node_modules -/.pnp -.pnp.js -/coverage -/prisma/db.sqlite -/prisma/db.sqlite-journal -/.next/ -/out/ -next-env.d.ts -/build -.env -.env*.local -built -.DS_Store -*.pem -npm-debug.log* +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ yarn-debug.log* yarn-error.log* +lerna-debug.log* .pnpm-debug.log* -.vercel -*.tsbuildinfo + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +\*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +\*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +\*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +\*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.cache +.parcel-cache + +# Next.js build output + .next -**/public/workbox-*.js -**/public/sw.js -**/public/sw.js.map -**/public/workbox-*.js.map -/built -/dist -manami.json -popularIds.json -PopularIds.json -database.json -/manga \ No newline at end of file +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +.cache/ + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp +.cache + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.\* + +# IntelliJ based IDEs +.idea diff --git a/anify-auth/README.md b/anify-auth/README.md index 096d55a..5e51008 100644 --- a/anify-auth/README.md +++ b/anify-auth/README.md @@ -1,2 +1,15 @@ -# anify-auth -This documentation will be updated soon. \ No newline at end of file +# anify-auth-recode + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run src/index.ts +``` + +This project was created using `bun init` in bun v1.0.1. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/anify-auth/db.sqlite b/anify-auth/db.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..64eb74be7fb12cca39fef3f0656ac53e4e0e9223 GIT binary patch literal 57344 zcmeI(?N8fA90zc_JcIy&N)z&{X;xH3qm4qKJgJ&AHyD{$%F9`tfrxL5r=G5fcW7-$J_3Mli zSEmlf{*6zMos9l7^84tYED0L~hF_qXh)GLx;(5%lbaGa4iBoN}ouxHN^_X<{2Q!(X zs+3i^lFvS=sB$*Htscn9D_N6rA>aKtc{k~QM>6$FoQg?vbK;MLYBiJaV*D}P`_i)V zFsJs4$#*B^-j+1wgTv^3W}wVlh~ z7s%miCcRW!Fx6-to7rCRz~`D}n1)NQNoi{R{9Z#-3)AD$gE>*~jNKO|Ti&W#o7&#{ zD(9%C`99H^j7bmX#q%%vqfsK18rGrfjY?Mc$Hf15YT(%TIRXVQM#xX>jTGxc>U=aF zla!Qr{-sy9qMvA1o#>^y?GU$0Eb4T+)rV6iuWdj$Pq1{i4dHawir)7pQ$J6~V$%G) z_~wUxxcH6bLjLQCtKs7(B|kKb{E_U3TyU`2XqAqQR#JXgDCATn-_Im(t2;_1SC$)^ z>5@xDcG{-t)*V8u8y3uyGZvEXU01`lXvug#97nw(E>xLbfgILe)PSXp?h`K&f7=?ZN zYvXm1VQxA0Av>5wM~k0n-!|J#5}nr} zEw*;NqfWzi3>qEmEyp-vYtYptEzrHD)@tz+fx!TlO?i8{PoUh9q3gujaqMQv1I)2= z7MAPsp(Rj)K|2x4rQK|qWN`XNnk8NwRl6}!y>4#w!X-R4c;`M~W~4^PrLUzyGo#y- zwD&ajYDx4?XJ0GcJm3}b$F1-z=(XeKlYpOh4<2FKX+@;+Q{jknnBbv|x9|Ttge}~P zI{EcllIHsncCp2;=Y<5{-R3)N5P$##AOHafKmY;|fB*y_009ULtH31h7_R?^b$HP) z2tWV=5P$##AOHafKmY;|fPg1}`~L_82tWV=5P$##AOHafKmY;|fWYtz;Qs&ck1=`( z0SG_<0uX=z1Rwwb2tWV=5WxL^!~g^!009U<00Izz00bZa0SG`~_yutPfB453J%j)R zAOHafKmY;|fB*y_009W#{y$;>0uX=z1Rwwb2tWV=5P$##ATay_xc@)=V~id`00Izz z00bZa0SG_<0uX=z1aSS27=Qo-AOHafKmY;|fB*y_009ULzW}cPhkuOGLkK_s0uX=z z1Rwwb2tWV=5P$&x|9^4T5!eql2tWV=5P$##AOHafKmY;|fB*zOn!x##7_Ug@W4nn& zVy(78mTRjUi))Q7ZSg*7Y%FeV*7U`#_4PE_Y}6X*4NWzvaeQY*yOUnN^RQ^$U&-yB zo-Dm=?klV7cKX|Vsc^Qpy!(9j)Y&Rk>YJN8`^B^G?4?d^=0.10.0" - } - }, - "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, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/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, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "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, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@eslint/eslintrc/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==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@fastify/ajv-compiler": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.5.0.tgz", - "integrity": "sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA==", - "dependencies": { - "ajv": "^8.11.0", - "ajv-formats": "^2.1.1", - "fast-uri": "^2.0.0" - } - }, - "node_modules/@fastify/ajv-compiler/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@fastify/ajv-compiler/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/@fastify/cors": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-8.3.0.tgz", - "integrity": "sha512-oj9xkka2Tg0MrwuKhsSUumcAkfp2YCnKxmFEusi01pjk1YrdDsuSYTHXEelWNW+ilSy/ApZq0c2SvhKrLX0H1g==", - "dependencies": { - "fastify-plugin": "^4.0.0", - "mnemonist": "0.39.5" - } - }, - "node_modules/@fastify/deepmerge": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-1.3.0.tgz", - "integrity": "sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==" - }, - "node_modules/@fastify/error": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.3.0.tgz", - "integrity": "sha512-dj7vjIn1Ar8sVXj2yAXiMNCJDmS9MQ9XMlIecX2dIzzhjSHCyKo4DdXjXMs7wKW2kj6yvVRSpuQjOZ3YLrh56w==" - }, - "node_modules/@fastify/fast-json-stringify-compiler": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", - "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", - "dependencies": { - "fast-json-stringify": "^5.7.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "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==", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" - }, - "node_modules/@ioredis/commands": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", - "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", - "license": "MIT" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "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, - "license": "MIT" - }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "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==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@prisma/client": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.15.0.tgz", - "integrity": "sha512-xnROvyABcGiwqRNdrObHVZkD9EjkJYHOmVdlKy1yGgI+XOzvMzJ4tRg3dz1pUlsyhKxXGCnjIQjWW+2ur+YXuw==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@prisma/engines-version": "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944" - }, - "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "prisma": "*" - }, - "peerDependenciesMeta": { - "prisma": { - "optional": true - } - } - }, - "node_modules/@prisma/debug": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-4.13.0.tgz", - "integrity": "sha512-JrltTewF/paRb5mcM5OvcEi9DtdX0sINOAswruxKQrwOLA7Phqb52OfY38MIzGrsrJ8iUGVqQ5bpYZYpxOGCsQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/debug": "4.1.7", - "debug": "4.3.4", - "strip-ansi": "6.0.1" - } - }, - "node_modules/@prisma/engines": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.0.0.tgz", - "integrity": "sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==", - "devOptional": true, - "hasInstallScript": true - }, - "node_modules/@prisma/engines-version": { - "version": "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944.tgz", - "integrity": "sha512-sVOig4tjGxxlYaFcXgE71f/rtFhzyYrfyfNFUsxCIEJyVKU9rdOWIlIwQ2NQ7PntvGnn+x0XuFo4OC1jvPJKzg==", - "license": "Apache-2.0" - }, - "node_modules/@prisma/generator-helper": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.13.0.tgz", - "integrity": "sha512-Zx9rtbsEIU/9DKnGRvmjLdyeyhzeeXNFp1alkRh1w//rQ5jTcobiay/jU4Qo+EQOs2bnWEfUeiBoOjfaysdLNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "4.13.0", - "@types/cross-spawn": "6.0.2", - "chalk": "4.1.2", - "cross-spawn": "7.0.3" - } - }, - "node_modules/@swc/helpers": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.3.17.tgz", - "integrity": "sha512-tb7Iu+oZ+zWJZ3HJqwx8oNwSDIU440hmVMDPhpACWQWnrZHK99Bxs70gT1L2dnr5Hg50ZRWEFkQCAnOVVV0z1Q==", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "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, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/cross-spawn": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", - "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "18.16.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.16.tgz", - "integrity": "sha512-NpaM49IGQQAUlBhHMF82QH80J08os4ZmyF9MkpCzWAGuOHqE4gTEbhzd7L3l5LmWuZ6E0OiC1FweQ4tsiW35+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz", - "integrity": "sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/type-utils": "5.59.8", - "@typescript-eslint/utils": "5.59.8", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz", - "integrity": "sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/typescript-estree": "5.59.8", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", - "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz", - "integrity": "sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.8", - "@typescript-eslint/utils": "5.59.8", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", - "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", - "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", - "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/typescript-estree": "5.59.8", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", - "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/abstract-logging": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", - "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "peer": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "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==", - "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==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/are-we-there-yet/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==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/are-we-there-yet/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==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT", - "peer": true - }, - "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/atomic-sleep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/avvio": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.2.1.tgz", - "integrity": "sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==", - "dependencies": { - "archy": "^1.0.0", - "debug": "^4.0.0", - "fastq": "^1.6.1" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "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/bcrypt": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", - "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", - "hasInstallScript": true, - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.11", - "node-addon-api": "^5.0.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brotli": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", - "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", - "license": "MIT", - "dependencies": { - "base64-js": "^1.1.2" - } - }, - "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/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "license": "MIT", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-parser": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", - "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", - "license": "MIT", - "dependencies": { - "cookie": "0.4.1", - "cookie-signature": "1.0.6" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/copyfiles": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", - "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^7.0.5", - "minimatch": "^3.0.3", - "mkdirp": "^1.0.4", - "noms": "0.0.0", - "through2": "^2.0.1", - "untildify": "^4.0.0", - "yargs": "^16.1.0" - }, - "bin": { - "copyfiles": "copyfiles", - "copyup": "copyfiles" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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, - "license": "MIT" - }, - "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==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==", - "license": "MIT" - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/deep-equal": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz", - "integrity": "sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.1", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/deep-equal/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "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==" - }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" - }, - "node_modules/denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/dfa": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", - "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==" - }, - "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, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "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", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dotenv": { - "version": "16.1.4", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", - "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "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==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-get-iterator/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT", - "peer": true - }, - "node_modules/eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/eslint/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", - "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-rate-limit": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.7.0.tgz", - "integrity": "sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 12.9.0" - }, - "peerDependencies": { - "express": "^4 || ^5" - } - }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "license": "MIT", - "peer": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT", - "peer": true - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "license": "MIT", - "peer": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-content-type-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.0.0.tgz", - "integrity": "sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==" - }, - "node_modules/fast-decode-uri-component": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", - "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==" - }, - "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==", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/fast-glob/node_modules/@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-glob/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/braces/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/fill-range/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-glob/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-json-stringify": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.8.0.tgz", - "integrity": "sha512-VVwK8CFMSALIvt14U8AvrSzQAwN/0vaVRiFFUVlpnXSnDGrSkOAO5MtzyN8oQNjLd5AqTW5OZRgyjoNuAuR3jQ==", - "dependencies": { - "@fastify/deepmerge": "^1.0.0", - "ajv": "^8.10.0", - "ajv-formats": "^2.1.1", - "fast-deep-equal": "^3.1.3", - "fast-uri": "^2.1.0", - "rfdc": "^1.2.0" - } - }, - "node_modules/fast-json-stringify/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "node_modules/fast-querystring": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", - "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", - "dependencies": { - "fast-decode-uri-component": "^1.0.1" - } - }, - "node_modules/fast-redact": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", - "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/fast-uri": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.2.0.tgz", - "integrity": "sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==" - }, - "node_modules/fastify": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.21.0.tgz", - "integrity": "sha512-tsu4bcwE4HetxqW8prA5fbC9bKHMYDp7jGEDWyzK1l90a3uOaLoIcQbdGcWeODNLVJviQnzh1wvIjTZE3MJFEg==", - "dependencies": { - "@fastify/ajv-compiler": "^3.5.0", - "@fastify/error": "^3.2.0", - "@fastify/fast-json-stringify-compiler": "^4.3.0", - "abstract-logging": "^2.0.1", - "avvio": "^8.2.1", - "fast-content-type-parse": "^1.0.0", - "fast-json-stringify": "^5.7.0", - "find-my-way": "^7.6.0", - "light-my-request": "^5.9.1", - "pino": "^8.12.0", - "process-warning": "^2.2.0", - "proxy-addr": "^2.0.7", - "rfdc": "^1.3.0", - "secure-json-parse": "^2.5.0", - "semver": "^7.5.0", - "tiny-lru": "^11.0.1" - } - }, - "node_modules/fastify-plugin": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", - "integrity": "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==" - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "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==", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "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, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT", - "peer": true - }, - "node_modules/find-my-way": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-7.6.2.tgz", - "integrity": "sha512-0OjHn1b1nCX3eVbm9ByeEHiscPYiHLfhei1wOUU9qffQkk98wE0Lo8VrVYfSGMgnSnDh86DxedduAnBf4nwUEw==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-querystring": "^1.0.0", - "safe-regex2": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" - }, - "node_modules/fontkit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-1.9.0.tgz", - "integrity": "sha512-HkW/8Lrk8jl18kzQHvAw9aTHe1cqsyx5sDnxncx652+CIfhawokEPkeM3BoIC+z/Xv7a0yMr0f3pRRwhGH455g==", - "dependencies": { - "@swc/helpers": "^0.3.13", - "brotli": "^1.3.2", - "clone": "^2.1.2", - "deep-equal": "^2.0.5", - "dfa": "^1.2.0", - "restructure": "^2.0.1", - "tiny-inflate": "^1.0.3", - "unicode-properties": "^1.3.1", - "unicode-trie": "^2.0.0" - } - }, - "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==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "license": "MIT", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "license": "MIT" - }, - "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==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "license": "ISC", - "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": "*" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", - "dev": true, - "license": "BSD" - }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "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/globby/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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/globby/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, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/globby/node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "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/globby/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/globby/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/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.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==", - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "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/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ioredis": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz", - "integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==", - "license": "MIT", - "dependencies": { - "@ioredis/commands": "^1.1.1", - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.4", - "denque": "^2.1.0", - "lodash.defaults": "^4.2.0", - "lodash.isarguments": "^3.1.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" - }, - "engines": { - "node": ">=12.22.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ioredis" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "license": "MIT" - }, - "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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.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==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jackspeak": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", - "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/light-my-request": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.10.0.tgz", - "integrity": "sha512-ZU2D9GmAcOUculTTdH9/zryej6n8TzT+fNGdNtm6SDp5MMMpHrJJkvAdE3c6d8d2chE9i+a//dS9CWZtisknqA==", - "dependencies": { - "cookie": "^0.5.0", - "process-warning": "^2.0.0", - "set-cookie-parser": "^2.4.1" - } - }, - "node_modules/light-my-request/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/linebreak": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz", - "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==", - "dependencies": { - "base64-js": "0.0.8", - "unicode-trie": "^2.0.0" - } - }, - "node_modules/linebreak/node_modules/base64-js": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", - "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", - "license": "MIT" - }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", - "license": "MIT" - }, - "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==" - }, - "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==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "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, - "license": "ISC" - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "license": "MIT", - "peer": 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, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "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, - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "peer": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mnemonist": { - "version": "0.39.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.5.tgz", - "integrity": "sha512-FPUtkhtJ0efmEFGpU14x7jGbTB+s18LrzRL2KgoWz9YvcY3cPomz8tih01GbHwnGk/OmkOKfqd/RAQoc8Lm7DQ==", - "dependencies": { - "obliterator": "^2.0.1" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true, - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" - }, - "node_modules/node-fetch": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/noms": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", - "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", - "dev": true, - "license": "ISC", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "~1.0.31" - } - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "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==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" - }, - "node_modules/on-exit-leak-free": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", - "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "license": "MIT", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true, - "license": "MIT" - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", - "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "license": "MIT", - "peer": true - }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-type/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/pdfkit": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/pdfkit/-/pdfkit-0.13.0.tgz", - "integrity": "sha512-AW79eHU5eLd2vgRDS9z3bSoi0FA+gYm+100LLosrQQMLUzOBGVOhG7ABcMFpJu7Bpg+MT74XYHi4k9EuU/9EZw==", - "dependencies": { - "crypto-js": "^4.0.0", - "fontkit": "^1.8.1", - "linebreak": "^1.0.2", - "png-js": "^1.0.0" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pino": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.15.0.tgz", - "integrity": "sha512-olUADJByk4twxccmAxb1RiGKOSvddHugCV3wkqjyv+3Sooa2KLrmXrKEWOKi0XPCLasRR5jBXxioE1jxUa4KzQ==", - "dependencies": { - "atomic-sleep": "^1.0.0", - "fast-redact": "^3.1.1", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "v1.0.0", - "pino-std-serializers": "^6.0.0", - "process-warning": "^2.0.0", - "quick-format-unescaped": "^4.0.3", - "real-require": "^0.2.0", - "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^3.1.0", - "thread-stream": "^2.0.0" - }, - "bin": { - "pino": "bin.js" - } - }, - "node_modules/pino-abstract-transport": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", - "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", - "dependencies": { - "readable-stream": "^4.0.0", - "split2": "^4.0.0" - } - }, - "node_modules/pino-abstract-transport/node_modules/readable-stream": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", - "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/pino-abstract-transport/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==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/pino-std-serializers": { - "version": "6.2.2", - "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/png-js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz", - "integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==" - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prisma": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.0.0.tgz", - "integrity": "sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA==", - "devOptional": true, - "hasInstallScript": true, - "dependencies": { - "@prisma/engines": "5.0.0" - }, - "bin": { - "prisma": "build/index.js" - }, - "engines": { - "node": ">=16.13" - } - }, - "node_modules/prisma-json-types-generator": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-2.4.0.tgz", - "integrity": "sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@prisma/generator-helper": "^4.10.1", - "tslib": "^2.5.0" - }, - "bin": { - "prisma-json-types-generator": "dist/bin.js" - }, - "engines": { - "node": ">=14.0" - }, - "funding": { - "url": "https://github.com/ArthurFiorette/prisma-json-types-generator?sponsor=1" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/process-warning": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", - "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "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/quick-format-unescaped": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", - "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/rate-limit-redis": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-3.0.2.tgz", - "integrity": "sha512-4SBK6AzIr9PKkCF4HmSDcJH2O2KKMF3fZEcsbNMXyaL5I9d6X71uOreUldFRiyrRyP+qkQrTxzJ38ZKKN+sScw==", - "license": "MIT", - "engines": { - "node": ">= 14.5.0" - }, - "peerDependencies": { - "express-rate-limit": "^6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/readable-stream/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/real-require": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", - "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", - "license": "MIT", - "dependencies": { - "redis-errors": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "dev": true, - "license": "MIT" - }, - "node_modules/restructure": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/restructure/-/restructure-2.0.1.tgz", - "integrity": "sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg==" - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" - }, - "node_modules/rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^10.2.5" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.2.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz", - "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "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==", - "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/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safe-regex2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz", - "integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==", - "dependencies": { - "ret": "~0.2.0" - } - }, - "node_modules/safe-regex2/node_modules/ret": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", - "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/secure-json-parse": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT", - "peer": true - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT", - "peer": true - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "license": "MIT", - "peer": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" - }, - "node_modules/set-cookie-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", - "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "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==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "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==", - "license": "ISC" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "license": "MIT", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sonic-boom": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", - "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", - "dependencies": { - "atomic-sleep": "^1.0.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true, - "license": "MIT" - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/standard-as-callback": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", - "license": "MIT" - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "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" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", - "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "license": "MIT" - }, - "node_modules/thread-stream": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.0.tgz", - "integrity": "sha512-xZYtOtmnA63zj04Q+F9bdEay5r47bvpo1CaNqsKi7TpoJHcotUez8Fkfo2RJWpW91lnnaApdpRbVwCWsy+ifcw==", - "dependencies": { - "real-require": "^0.2.0" - } - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/tiny-inflate": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", - "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" - }, - "node_modules/tiny-lru": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.0.1.tgz", - "integrity": "sha512-iNgFugVuQgBKrqeO/mpiTTgmBsTP0WL6yeuLfLs/Ctf0pI/ixGqIRm8sDCwMcXGe9WWvt2sGXI5mNqZbValmJg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/to-regex-range/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, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/to-regex/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tscpaths": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/tscpaths/-/tscpaths-0.0.9.tgz", - "integrity": "sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^2.20.0", - "globby": "^9.2.0" - }, - "bin": { - "tscpaths": "cjs/index.js" - } - }, - "node_modules/tscpaths/node_modules/globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tscpaths/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "license": "0BSD" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "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==", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unicode-properties": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz", - "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==", - "dependencies": { - "base64-js": "^1.3.0", - "unicode-trie": "^2.0.0" - } - }, - "node_modules/unicode-trie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", - "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", - "dependencies": { - "pako": "^0.2.5", - "tiny-inflate": "^1.0.0" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "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, - "license": "MIT" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/whatwg-url": { - "version": "5.0.0", - "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/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "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==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", - "dependencies": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "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/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "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, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "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==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/anify-auth/package.json b/anify-auth/package.json index 56ab60a..e4fd320 100644 --- a/anify-auth/package.json +++ b/anify-auth/package.json @@ -1,73 +1,29 @@ { - "devDependencies": { - "@types/node": "^18.16.16", - "@typescript-eslint/eslint-plugin": "^5.59.8", - "@typescript-eslint/parser": "^5.59.8", - "copyfiles": "^2.4.1", - "prettier": "2.8.8", - "prisma": "^5.0.0", - "prisma-json-types-generator": "^2.4.0", - "rimraf": "^5.0.1", - "ts-node": "^10.9.1", - "tsconfig-paths": "^4.2.0", - "tscpaths": "^0.0.9", - "tslib": "^2.5.3", - "typescript": "^4.9.5" - }, - "name": "anify-auth", - "description": "Anify authentication manager", - "version": "1.0.0", - "source": "src/index.ts", - "bin": "dist/index.js", + "name": "anify-auth-recode", + "module": "src/index.ts", + "type": "module", "scripts": { - "dev": "ts-node -r tsconfig-paths/register src/index.ts", - "start": "node dist/index.js", - "copy-files": "copyfiles -u 1 src/**/*.json dist/", - "build": "npm run check:env && npm run build:db && npm run lint && npm run build:ts", - "rebuild": "npm run clean && npm run build:ts", - "build:ts": "tsc --project tsconfig.json && tscpaths -p tsconfig.json -s ./src -o ./dist && npm run copy-files", - "build:db": "ts-node -r tsconfig-paths/register src/scripts/buildDb.ts", - "db:generate": "npx prisma generate", - "db:push": "npx prisma db push", - "db:validate": "npx prisma validate", - "clean": "rimraf dist/", - "export": "ts-node -r tsconfig-paths/register src/scripts/export.ts", - "clear": "ts-node -r tsconfig-paths/register src/scripts/clear.ts", - "import": "ts-node -r tsconfig-paths/register src/scripts/import.ts", - "check:env": "ts-node -r tsconfig-paths/register src/scripts/checkEnv.ts", - "redis:flush": "ts-node -r tsconfig-paths/register src/scripts/flushSafe.ts", + "start": "bun run dist/index.js", + "dev": "bun run src/index.ts", + "build": "bun build ./src/index.ts --outdir ./dist --target node", "prettier": "prettier --write .", "eslint": "eslint --ext .ts src/** --fix", - "lint": "npm run prettier && npm run eslint" + "lint": "bun run prettier && bun run eslint" }, - "repository": { - "type": "git", - "url": "git+https://github.com/Eltik/Anify.git" - }, - "author": "eltik", - "license": "ISC", - "bugs": { - "url": "https://github.com/Eltik/Anify/issues" + "devDependencies": { + "@types/bcryptjs": "^2.4.3", + "@typescript-eslint/eslint-plugin": "^6.7.0", + "@typescript-eslint/parser": "^6.7.0", + "bun-types": "latest", + "eslint": "^8.49.0", + "prettier": "^3.0.3" }, - "homepage": "https://anify.tv", - "directories": { - "lib": "src" + "peerDependencies": { + "typescript": "^5.0.0" }, "dependencies": { - "@fastify/cors": "^8.3.0", - "@prisma/client": "^4.15.0", - "bcrypt": "^5.1.1", - "body-parser": "^1.20.2", - "cheerio": "1.0.0-rc.12", + "bcryptjs": "^2.4.3", "colors": "^1.4.0", - "cookie-parser": "^1.4.6", - "cors": "^2.8.5", - "crypto-js": "^4.1.1", - "dotenv": "^16.1.4", - "eslint": "^8.45.0", - "fastify": "^4.21.0", - "ioredis": "^5.3.2", - "pdfkit": "^0.13.0", - "rate-limit-redis": "^3.0.2" + "ioredis": "^5.3.2" } -} +} \ No newline at end of file diff --git a/anify-auth/pnpm-lock.yaml b/anify-auth/pnpm-lock.yaml deleted file mode 100644 index 21202e4..0000000 --- a/anify-auth/pnpm-lock.yaml +++ /dev/null @@ -1,5819 +0,0 @@ -lockfileVersion: '6.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -dependencies: - '@extractus/article-extractor': - specifier: ^7.2.16 - version: 7.2.16 - '@prisma/client': - specifier: ^4.15.0 - version: 4.15.0(prisma@5.0.0) - body-parser: - specifier: ^1.20.2 - version: 1.20.2 - cheerio: - specifier: 1.0.0-rc.12 - version: 1.0.0-rc.12 - cloudscraper-ts: - specifier: ^1.0.9 - version: 1.0.9 - colors: - specifier: ^1.4.0 - version: 1.4.0 - cookie-parser: - specifier: ^1.4.6 - version: 1.4.6 - cors: - specifier: ^2.8.5 - version: 2.8.5 - crypto-js: - specifier: ^4.1.1 - version: 4.1.1 - dotenv: - specifier: ^16.1.4 - version: 16.1.4 - eslint: - specifier: ^8.45.0 - version: 8.45.0 - eventemitter2: - specifier: ^6.4.9 - version: 6.4.9 - express: - specifier: ^4.18.2 - version: 4.18.2 - express-domain-middleware: - specifier: ^0.1.0 - version: 0.1.0 - express-rate-limit: - specifier: ^6.7.0 - version: 6.7.0(express@4.18.2) - ioredis: - specifier: ^5.3.2 - version: 5.3.2 - mathjs: - specifier: ^11.8.0 - version: 11.8.0 - rate-limit-redis: - specifier: ^3.0.2 - version: 3.0.2(express-rate-limit@6.7.0) - -devDependencies: - '@jest/globals': - specifier: ^29.5.0 - version: 29.5.0 - '@types/jest': - specifier: ^29.5.2 - version: 29.5.2 - '@types/node': - specifier: ^18.16.16 - version: 18.16.16 - '@typescript-eslint/eslint-plugin': - specifier: ^5.59.8 - version: 5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.45.0)(typescript@4.9.5) - '@typescript-eslint/parser': - specifier: ^5.59.8 - version: 5.59.8(eslint@8.45.0)(typescript@4.9.5) - copyfiles: - specifier: ^2.4.1 - version: 2.4.1 - jest: - specifier: ^29.5.0 - version: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - prettier: - specifier: 2.8.8 - version: 2.8.8 - prisma: - specifier: ^5.0.0 - version: 5.0.0 - prisma-json-types-generator: - specifier: ^2.4.0 - version: 2.4.0 - rimraf: - specifier: ^5.0.1 - version: 5.0.1 - ts-jest: - specifier: ^29.1.0 - version: 29.1.0(@babel/core@7.22.1)(jest@29.5.0)(typescript@4.9.5) - ts-node: - specifier: ^10.9.1 - version: 10.9.1(@types/node@18.16.16)(typescript@4.9.5) - tsconfig-paths: - specifier: ^4.2.0 - version: 4.2.0 - tscpaths: - specifier: ^0.0.9 - version: 0.0.9 - tslib: - specifier: ^2.5.3 - version: 2.5.3 - typescript: - specifier: ^4.9.5 - version: 4.9.5 - -packages: - - /@aashutoshrathi/word-wrap@1.2.6: - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - - /@ampproject/remapping@2.2.1: - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - - /@babel/code-frame@7.21.4: - resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.18.6 - - /@babel/compat-data@7.22.3: - resolution: {integrity: sha512-aNtko9OPOwVESUFp3MZfD8Uzxl7JzSeJpd7npIoxCasU37PFbAQRpKglkaKwlHOyeJdrREpo8TW8ldrkYWwvIQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/core@7.22.1: - resolution: {integrity: sha512-Hkqu7J4ynysSXxmAahpN1jjRwVJ+NdpraFLIWflgjpVob3KNyK3/tIUc7Q7szed8WMp0JNa7Qtd1E9Oo22F9gA==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.22.3 - '@babel/helper-compilation-targets': 7.22.1(@babel/core@7.22.1) - '@babel/helper-module-transforms': 7.22.1 - '@babel/helpers': 7.22.3 - '@babel/parser': 7.22.4 - '@babel/template': 7.21.9 - '@babel/traverse': 7.22.4 - '@babel/types': 7.22.4 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/generator@7.22.3: - resolution: {integrity: sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - jsesc: 2.5.2 - dev: true - - /@babel/helper-compilation-targets@7.22.1(@babel/core@7.22.1): - resolution: {integrity: sha512-Rqx13UM3yVB5q0D/KwQ8+SPfX/+Rnsy1Lw1k/UwOC4KC6qrzIQoY3lYnBu5EHKBlEHHcj0M0W8ltPSkD8rqfsQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.22.3 - '@babel/core': 7.22.1 - '@babel/helper-validator-option': 7.21.0 - browserslist: 4.21.7 - lru-cache: 5.1.1 - semver: 6.3.0 - dev: true - - /@babel/helper-environment-visitor@7.22.1: - resolution: {integrity: sha512-Z2tgopurB/kTbidvzeBrc2To3PUP/9i5MUe+fU6QJCQDyPwSH2oRapkLw3KGECDYSjhQZCNxEvNvZlLw8JjGwA==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-function-name@7.21.0: - resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.21.9 - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-hoist-variables@7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-module-imports@7.21.4: - resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-module-transforms@7.22.1: - resolution: {integrity: sha512-dxAe9E7ySDGbQdCVOY/4+UcD8M9ZFqZcZhSPsPacvCG4M+9lwtDDQfI2EoaSvmf7W/8yCBkGU0m7Pvt1ru3UZw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.22.1 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-simple-access': 7.21.5 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.21.9 - '@babel/traverse': 7.22.4 - '@babel/types': 7.22.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-plugin-utils@7.21.5: - resolution: {integrity: sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-simple-access@7.21.5: - resolution: {integrity: sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-split-export-declaration@7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/helper-string-parser@7.21.5: - resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier@7.19.1: - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} - engines: {node: '>=6.9.0'} - - /@babel/helper-validator-option@7.21.0: - resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helpers@7.22.3: - resolution: {integrity: sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.21.9 - '@babel/traverse': 7.22.4 - '@babel/types': 7.22.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/highlight@7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.19.1 - chalk: 2.4.2 - js-tokens: 4.0.0 - - /@babel/parser@7.22.4: - resolution: {integrity: sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.1): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.1): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.1): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.22.1): - resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.1): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.1): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.1): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.1): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.22.1): - resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.1 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/runtime@7.22.3: - resolution: {integrity: sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.11 - dev: false - - /@babel/template@7.21.9: - resolution: {integrity: sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.21.4 - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - dev: true - - /@babel/traverse@7.22.4: - resolution: {integrity: sha512-Tn1pDsjIcI+JcLKq1AVlZEr4226gpuAQTsLMorsYg9tuS/kG7nuwwJ4AB8jfQuEgb/COBwR/DqJxmoiYFu5/rQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.22.3 - '@babel/helper-environment-visitor': 7.22.1 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/types@7.22.4: - resolution: {integrity: sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.21.5 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: true - - /@bcoe/v8-coverage@0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true - - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - - /@eslint-community/eslint-utils@4.4.0(eslint@8.45.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.45.0 - eslint-visitor-keys: 3.4.1 - - /@eslint-community/regexpp@4.5.1: - resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - /@eslint/eslintrc@2.1.0: - resolution: {integrity: sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.20.0 - ignore: 5.2.4 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - /@eslint/js@8.44.0: - resolution: {integrity: sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - /@extractus/article-extractor@7.2.16: - resolution: {integrity: sha512-LV55IG1QOMTDzbb4Cb6TQ8LMoh+smtr6pIAEA7IWTUw8VbSQZtRPr0Go6akJSb/XaaKv4KrtsxNyrhyAjtWrcA==} - engines: {node: '>= 14'} - dependencies: - '@mozilla/readability': 0.4.4 - bellajs: 11.1.2 - cross-fetch: 3.1.6 - linkedom: 0.14.26 - sanitize-html: 2.10.0 - transitivePeerDependencies: - - encoding - dev: false - - /@humanwhocodes/config-array@0.11.10: - resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - /@humanwhocodes/object-schema@1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - - /@ioredis/commands@1.2.0: - resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} - dev: false - - /@isaacs/cliui@8.0.2: - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - dependencies: - string-width: 5.1.2 - string-width-cjs: /string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: /strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: true - - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - dev: true - - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - dev: true - - /@jest/console@29.5.0: - resolution: {integrity: sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - slash: 3.0.0 - dev: true - - /@jest/core@29.5.0(ts-node@10.9.1): - resolution: {integrity: sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==} - 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 - dependencies: - '@jest/console': 29.5.0 - '@jest/reporters': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.8.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.5.0 - jest-config: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - jest-haste-map: 29.5.0 - jest-message-util: 29.5.0 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-resolve-dependencies: 29.5.0 - jest-runner: 29.5.0 - jest-runtime: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - jest-watcher: 29.5.0 - micromatch: 4.0.5 - pretty-format: 29.5.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - supports-color - - ts-node - dev: true - - /@jest/environment@29.5.0: - resolution: {integrity: sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/fake-timers': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - jest-mock: 29.5.0 - dev: true - - /@jest/expect-utils@29.5.0: - resolution: {integrity: sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.4.3 - dev: true - - /@jest/expect@29.5.0: - resolution: {integrity: sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - expect: 29.5.0 - jest-snapshot: 29.5.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/fake-timers@29.5.0: - resolution: {integrity: sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@sinonjs/fake-timers': 10.2.0 - '@types/node': 18.16.16 - jest-message-util: 29.5.0 - jest-mock: 29.5.0 - jest-util: 29.5.0 - dev: true - - /@jest/globals@29.5.0: - resolution: {integrity: sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.5.0 - '@jest/expect': 29.5.0 - '@jest/types': 29.5.0 - jest-mock: 29.5.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/reporters@29.5.0: - resolution: {integrity: sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==} - 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 - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 18.16.16 - chalk: 4.1.2 - collect-v8-coverage: 1.0.1 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 5.2.1 - istanbul-lib-report: 3.0.0 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.5 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - jest-worker: 29.5.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.1.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/schemas@29.4.3: - resolution: {integrity: sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@sinclair/typebox': 0.25.24 - dev: true - - /@jest/source-map@29.4.3: - resolution: {integrity: sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jridgewell/trace-mapping': 0.3.18 - callsites: 3.1.0 - graceful-fs: 4.2.11 - dev: true - - /@jest/test-result@29.5.0: - resolution: {integrity: sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.5.0 - '@jest/types': 29.5.0 - '@types/istanbul-lib-coverage': 2.0.4 - collect-v8-coverage: 1.0.1 - dev: true - - /@jest/test-sequencer@29.5.0: - resolution: {integrity: sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.5.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - slash: 3.0.0 - dev: true - - /@jest/transform@29.5.0: - resolution: {integrity: sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.22.1 - '@jest/types': 29.5.0 - '@jridgewell/trace-mapping': 0.3.18 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - jest-regex-util: 29.4.3 - jest-util: 29.5.0 - micromatch: 4.0.5 - pirates: 4.0.5 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/types@29.5.0: - resolution: {integrity: sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.4.3 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.1 - '@types/node': 18.16.16 - '@types/yargs': 17.0.24 - chalk: 4.1.2 - dev: true - - /@jridgewell/gen-mapping@0.3.3: - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - - /@jridgewell/resolve-uri@3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/sourcemap-codec@1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true - - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true - - /@jridgewell/trace-mapping@0.3.18: - resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - - /@mozilla/readability@0.4.4: - resolution: {integrity: sha512-MCgZyANpJ6msfvVMi6+A0UAsvZj//4OHREYUB9f2087uXHVoU+H+SWhuihvb1beKpM323bReQPRio0WNk2+V6g==} - engines: {node: '>=14.0.0'} - dev: false - - /@mrmlnc/readdir-enhanced@2.2.1: - resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==} - engines: {node: '>=4'} - dependencies: - call-me-maybe: 1.0.2 - glob-to-regexp: 0.3.0 - dev: true - - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - /@nodelib/fs.stat@1.1.3: - resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==} - engines: {node: '>= 6'} - dev: true - - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 - - /@pkgjs/parseargs@0.11.0: - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - requiresBuild: true - dev: true - optional: true - - /@prisma/client@4.15.0(prisma@5.0.0): - resolution: {integrity: sha512-xnROvyABcGiwqRNdrObHVZkD9EjkJYHOmVdlKy1yGgI+XOzvMzJ4tRg3dz1pUlsyhKxXGCnjIQjWW+2ur+YXuw==} - engines: {node: '>=14.17'} - requiresBuild: true - peerDependencies: - prisma: '*' - peerDependenciesMeta: - prisma: - optional: true - dependencies: - '@prisma/engines-version': 4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944 - prisma: 5.0.0 - dev: false - - /@prisma/debug@4.15.0: - resolution: {integrity: sha512-dkbPz+gOVlWDBAaOEseSpAUz9NppT38UlwdryPyrwct6OClLirNC7wH+TpAQk5OZp9x59hNnfDz+T7XvL1v0/Q==} - dependencies: - '@types/debug': 4.1.8 - debug: 4.3.4 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@prisma/engines-version@4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944: - resolution: {integrity: sha512-sVOig4tjGxxlYaFcXgE71f/rtFhzyYrfyfNFUsxCIEJyVKU9rdOWIlIwQ2NQ7PntvGnn+x0XuFo4OC1jvPJKzg==} - dev: false - - /@prisma/engines@5.0.0: - resolution: {integrity: sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==} - requiresBuild: true - - /@prisma/generator-helper@4.15.0: - resolution: {integrity: sha512-JVHNgXr0LrcqXqmFrs+BzxfyRL6cFD5GLTMVWfCLU7kqSJdWuZxfoZW995tg6mOXnBgPTf6Ocv3RY4RLQq8k4g==} - dependencies: - '@prisma/debug': 4.15.0 - '@types/cross-spawn': 6.0.2 - cross-spawn: 7.0.3 - kleur: 4.1.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@sinclair/typebox@0.25.24: - resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} - dev: true - - /@sinonjs/commons@3.0.0: - resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} - dependencies: - type-detect: 4.0.8 - dev: true - - /@sinonjs/fake-timers@10.2.0: - resolution: {integrity: sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==} - dependencies: - '@sinonjs/commons': 3.0.0 - dev: true - - /@tsconfig/node10@1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true - - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - - /@tsconfig/node16@1.0.4: - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true - - /@types/babel__core@7.20.1: - resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} - dependencies: - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - '@types/babel__generator': 7.6.4 - '@types/babel__template': 7.4.1 - '@types/babel__traverse': 7.20.1 - dev: true - - /@types/babel__generator@7.6.4: - resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@types/babel__template@7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} - dependencies: - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - dev: true - - /@types/babel__traverse@7.20.1: - resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@types/bluebird@3.5.38: - resolution: {integrity: sha512-yR/Kxc0dd4FfwtEoLZMoqJbM/VE/W7hXn/MIjb+axcwag0iFmSPK7OBUZq1YWLynJUoWQkfUrI7T0HDqGApNSg==} - dev: false - - /@types/caseless@0.12.2: - resolution: {integrity: sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==} - dev: false - - /@types/cross-spawn@6.0.2: - resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} - dependencies: - '@types/node': 18.16.16 - dev: true - - /@types/debug@4.1.8: - resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} - dependencies: - '@types/ms': 0.7.31 - dev: true - - /@types/eslint-visitor-keys@1.0.0: - resolution: {integrity: sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==} - dev: false - - /@types/glob@7.2.0: - resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} - dependencies: - '@types/minimatch': 5.1.2 - '@types/node': 18.16.16 - dev: true - - /@types/graceful-fs@4.1.6: - resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} - dependencies: - '@types/node': 18.16.16 - dev: true - - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} - dev: true - - /@types/istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} - dependencies: - '@types/istanbul-lib-coverage': 2.0.4 - dev: true - - /@types/istanbul-reports@3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} - dependencies: - '@types/istanbul-lib-report': 3.0.0 - dev: true - - /@types/jest@29.5.2: - resolution: {integrity: sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==} - dependencies: - expect: 29.5.0 - pretty-format: 29.5.0 - dev: true - - /@types/json-schema@7.0.12: - resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} - - /@types/minimatch@5.1.2: - resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} - dev: true - - /@types/ms@0.7.31: - resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} - dev: true - - /@types/node@18.16.16: - resolution: {integrity: sha512-NpaM49IGQQAUlBhHMF82QH80J08os4ZmyF9MkpCzWAGuOHqE4gTEbhzd7L3l5LmWuZ6E0OiC1FweQ4tsiW35+g==} - - /@types/prettier@2.7.3: - resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} - dev: true - - /@types/request-promise@4.1.48: - resolution: {integrity: sha512-sLsfxfwP5G3E3U64QXxKwA6ctsxZ7uKyl4I28pMj3JvV+ztWECRns73GL71KMOOJME5u1A5Vs5dkBqyiR1Zcnw==} - dependencies: - '@types/bluebird': 3.5.38 - '@types/request': 2.48.8 - dev: false - - /@types/request@2.48.8: - resolution: {integrity: sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==} - dependencies: - '@types/caseless': 0.12.2 - '@types/node': 18.16.16 - '@types/tough-cookie': 4.0.2 - form-data: 2.5.1 - dev: false - - /@types/semver@7.5.0: - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} - dev: true - - /@types/stack-utils@2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - dev: true - - /@types/tough-cookie@4.0.2: - resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} - dev: false - - /@types/yargs-parser@21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} - dev: true - - /@types/yargs@17.0.24: - resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} - dependencies: - '@types/yargs-parser': 21.0.0 - dev: true - - /@typescript-eslint/eslint-plugin@2.34.0(@typescript-eslint/parser@2.34.0)(eslint@6.8.0)(typescript@3.9.10): - resolution: {integrity: sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - '@typescript-eslint/parser': ^2.0.0 - eslint: ^5.0.0 || ^6.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/experimental-utils': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/parser': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - eslint: 6.8.0 - functional-red-black-tree: 1.0.1 - regexpp: 3.2.0 - tsutils: 3.21.0(typescript@3.9.10) - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/eslint-plugin@5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.45.0)(typescript@4.9.5): - resolution: {integrity: sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 5.59.8(eslint@8.45.0)(typescript@4.9.5) - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/type-utils': 5.59.8(eslint@8.45.0)(typescript@4.9.5) - '@typescript-eslint/utils': 5.59.8(eslint@8.45.0)(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.45.0 - grapheme-splitter: 1.0.4 - ignore: 5.2.4 - natural-compare-lite: 1.4.0 - semver: 7.5.1 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/experimental-utils@2.34.0(eslint@6.8.0)(typescript@3.9.10): - resolution: {integrity: sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - eslint: '*' - dependencies: - '@types/json-schema': 7.0.12 - '@typescript-eslint/typescript-estree': 2.34.0(typescript@3.9.10) - eslint: 6.8.0 - eslint-scope: 5.1.1 - eslint-utils: 2.1.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: false - - /@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10): - resolution: {integrity: sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - eslint: ^5.0.0 || ^6.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@types/eslint-visitor-keys': 1.0.0 - '@typescript-eslint/experimental-utils': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/typescript-estree': 2.34.0(typescript@3.9.10) - eslint: 6.8.0 - eslint-visitor-keys: 1.3.0 - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/parser@5.59.8(eslint@8.45.0)(typescript@4.9.5): - resolution: {integrity: sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.45.0 - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/scope-manager@5.59.8: - resolution: {integrity: sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/visitor-keys': 5.59.8 - dev: true - - /@typescript-eslint/type-utils@5.59.8(eslint@8.45.0)(typescript@4.9.5): - resolution: {integrity: sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) - '@typescript-eslint/utils': 5.59.8(eslint@8.45.0)(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.45.0 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/types@5.59.8: - resolution: {integrity: sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /@typescript-eslint/typescript-estree@2.34.0(typescript@3.9.10): - resolution: {integrity: sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - debug: 4.3.4 - eslint-visitor-keys: 1.3.0 - glob: 7.2.3 - is-glob: 4.0.3 - lodash: 4.17.21 - semver: 7.5.1 - tsutils: 3.21.0(typescript@3.9.10) - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/typescript-estree@5.59.8(typescript@4.9.5): - resolution: {integrity: sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/visitor-keys': 5.59.8 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.1 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/utils@5.59.8(eslint@8.45.0)(typescript@4.9.5): - resolution: {integrity: sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) - '@types/json-schema': 7.0.12 - '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 5.59.8 - '@typescript-eslint/types': 5.59.8 - '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5) - eslint: 8.45.0 - eslint-scope: 5.1.1 - semver: 7.5.1 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/visitor-keys@5.59.8: - resolution: {integrity: sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.59.8 - eslint-visitor-keys: 3.4.1 - dev: true - - /accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - dev: false - - /acorn-jsx@5.3.2(acorn@7.4.1): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 7.4.1 - dev: false - - /acorn-jsx@5.3.2(acorn@8.10.0): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.10.0 - - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn@7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: false - - /acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} - engines: {node: '>=0.4.0'} - hasBin: true - - /acorn@8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - /ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - - /ansi-regex@4.1.1: - resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} - engines: {node: '>=6'} - dev: false - - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - /ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - dev: true - - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - - /ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - dev: true - - /ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - dev: true - - /anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - dev: true - - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - /arr-diff@4.0.0: - resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} - engines: {node: '>=0.10.0'} - dev: true - - /arr-flatten@1.1.0: - resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} - engines: {node: '>=0.10.0'} - dev: true - - /arr-union@3.1.0: - resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} - engines: {node: '>=0.10.0'} - dev: true - - /array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - dev: false - - /array-union@1.0.2: - resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} - engines: {node: '>=0.10.0'} - dependencies: - array-uniq: 1.0.3 - dev: true - - /array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true - - /array-uniq@1.0.3: - resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} - engines: {node: '>=0.10.0'} - dev: true - - /array-unique@0.3.2: - resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} - engines: {node: '>=0.10.0'} - dev: true - - /asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - dependencies: - safer-buffer: 2.1.2 - dev: false - - /assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - dev: false - - /assign-symbols@1.0.0: - resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} - engines: {node: '>=0.10.0'} - dev: true - - /astral-regex@1.0.0: - resolution: {integrity: sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==} - engines: {node: '>=4'} - dev: false - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - - /atob@2.1.2: - resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} - engines: {node: '>= 4.5.0'} - hasBin: true - dev: true - - /aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - dev: false - - /aws4@1.12.0: - resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} - dev: false - - /babel-jest@29.5.0(@babel/core@7.22.1): - resolution: {integrity: sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - dependencies: - '@babel/core': 7.22.1 - '@jest/transform': 29.5.0 - '@types/babel__core': 7.20.1 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.5.0(@babel/core@7.22.1) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - dependencies: - '@babel/helper-plugin-utils': 7.21.5 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-jest-hoist@29.5.0: - resolution: {integrity: sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/template': 7.21.9 - '@babel/types': 7.22.4 - '@types/babel__core': 7.20.1 - '@types/babel__traverse': 7.20.1 - dev: true - - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.1): - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.1 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.1) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.1) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.1) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.1) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.1) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.1) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.1) - dev: true - - /babel-preset-jest@29.5.0(@babel/core@7.22.1): - resolution: {integrity: sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.1 - babel-plugin-jest-hoist: 29.5.0 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.1) - dev: true - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: false - - /base@0.11.2: - resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} - engines: {node: '>=0.10.0'} - dependencies: - cache-base: 1.0.1 - class-utils: 0.3.6 - component-emitter: 1.3.0 - define-property: 1.0.0 - isobject: 3.0.1 - mixin-deep: 1.3.2 - pascalcase: 0.1.1 - dev: true - - /bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - dependencies: - tweetnacl: 0.14.5 - dev: false - - /bellajs@11.1.2: - resolution: {integrity: sha512-2Fy3Km5JKyIy/KunW3oica2gZtkjD2qSqti2Q3xPhHvXXdMbc+32pEMOPG+xrSat0BXVhRjHIx++lzxIPK0GqQ==} - engines: {node: '>= 14'} - dev: false - - /bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - dev: false - - /body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.1 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: false - - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - - /braces@2.3.2: - resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} - engines: {node: '>=0.10.0'} - dependencies: - arr-flatten: 1.1.0 - array-unique: 0.3.2 - extend-shallow: 2.0.1 - fill-range: 4.0.0 - isobject: 3.0.1 - repeat-element: 1.1.4 - snapdragon: 0.8.2 - snapdragon-node: 2.1.1 - split-string: 3.1.0 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - - /brotli@1.3.3: - resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} - dependencies: - base64-js: 1.5.1 - dev: false - - /browserslist@4.21.7: - resolution: {integrity: sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001494 - electron-to-chromium: 1.4.419 - node-releases: 2.0.12 - update-browserslist-db: 1.0.11(browserslist@4.21.7) - dev: true - - /bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} - dependencies: - fast-json-stable-stringify: 2.1.0 - dev: true - - /bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - dependencies: - node-int64: 0.4.0 - dev: true - - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - dev: false - - /cache-base@1.0.1: - resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} - engines: {node: '>=0.10.0'} - dependencies: - collection-visit: 1.0.0 - component-emitter: 1.3.0 - get-value: 2.0.6 - has-value: 1.0.0 - isobject: 3.0.1 - set-value: 2.0.1 - to-object-path: 0.3.0 - union-value: 1.0.1 - unset-value: 1.0.0 - dev: true - - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 - dev: false - - /call-me-maybe@1.0.2: - resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - dev: true - - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: true - - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - dev: true - - /caniuse-lite@1.0.30001494: - resolution: {integrity: sha512-sY2B5Qyl46ZzfYDegrl8GBCzdawSLT4ThM9b9F+aDYUrAG2zCOyMbd2Tq34mS1g4ZKBfjRlzOohQMxx28x6wJg==} - dev: true - - /caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - dev: false - - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - /char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - dev: true - - /chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: false - - /cheerio-select@2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - dependencies: - boolbase: 1.0.0 - css-select: 5.1.0 - css-what: 6.1.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - dev: false - - /cheerio@1.0.0-rc.12: - resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} - engines: {node: '>= 6'} - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.1.0 - htmlparser2: 8.0.2 - parse5: 7.1.2 - parse5-htmlparser2-tree-adapter: 7.0.0 - dev: false - - /ci-info@3.8.0: - resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} - engines: {node: '>=8'} - dev: true - - /cjs-module-lexer@1.2.2: - resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} - dev: true - - /class-utils@0.3.6: - resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - define-property: 0.2.5 - isobject: 3.0.1 - static-extend: 0.1.2 - dev: true - - /cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: false - - /cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} - dev: false - - /cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /cloudscraper-ts@1.0.9: - resolution: {integrity: sha512-aPJC1pOI9xfceelvDonKg2bueH3wbuKMSEk40mnIAoXftv1Ut0d1qI4fu9w2UUCnbwUb6TJIm9jk6zzvkC4BWg==} - dependencies: - '@types/request-promise': 4.1.48 - '@typescript-eslint/eslint-plugin': 2.34.0(@typescript-eslint/parser@2.34.0)(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/parser': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - brotli: 1.3.3 - es6-symbol: 3.1.3 - eslint: 6.8.0 - request: 2.88.2 - request-promise: 4.2.6(request@2.88.2) - request-promise-core: 1.1.4(request@2.88.2) - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - dev: false - - /cluster-key-slot@1.1.2: - resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} - engines: {node: '>=0.10.0'} - dev: false - - /co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: true - - /collect-v8-coverage@1.0.1: - resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} - dev: true - - /collection-visit@1.0.0: - resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} - engines: {node: '>=0.10.0'} - dependencies: - map-visit: 1.0.0 - object-visit: 1.0.1 - dev: true - - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - /colors@1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} - dev: false - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true - - /complex.js@2.1.1: - resolution: {integrity: sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==} - dev: false - - /component-emitter@1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} - dev: true - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - /content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - dev: false - - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true - - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true - - /cookie-parser@1.4.6: - resolution: {integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==} - engines: {node: '>= 0.8.0'} - dependencies: - cookie: 0.4.1 - cookie-signature: 1.0.6 - dev: false - - /cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - dev: false - - /cookie@0.4.1: - resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==} - engines: {node: '>= 0.6'} - dev: false - - /cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - dev: false - - /copy-descriptor@0.1.1: - resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} - engines: {node: '>=0.10.0'} - dev: true - - /copyfiles@2.4.1: - resolution: {integrity: sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==} - hasBin: true - dependencies: - glob: 7.2.3 - minimatch: 3.1.2 - mkdirp: 1.0.4 - noms: 0.0.0 - through2: 2.0.5 - untildify: 4.0.0 - yargs: 16.2.0 - dev: true - - /core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - dev: false - - /core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: true - - /cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - dev: false - - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - - /cross-fetch@3.1.6: - resolution: {integrity: sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==} - dependencies: - node-fetch: 2.6.11 - transitivePeerDependencies: - - encoding - dev: false - - /cross-spawn@6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.2 - shebang-command: 1.2.0 - which: 1.3.1 - dev: false - - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - /crypto-js@4.1.1: - resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} - dev: false - - /css-select@5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} - dependencies: - boolbase: 1.0.0 - css-what: 6.1.0 - domhandler: 5.0.3 - domutils: 3.1.0 - nth-check: 2.1.1 - dev: false - - /css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} - engines: {node: '>= 6'} - dev: false - - /cssom@0.5.0: - resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - dev: false - - /d@1.0.1: - resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} - dependencies: - es5-ext: 0.10.62 - type: 1.2.0 - dev: false - - /dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - dependencies: - assert-plus: 1.0.0 - dev: false - - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - - /decimal.js@10.4.3: - resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - dev: false - - /decode-uri-component@0.2.2: - resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} - engines: {node: '>=0.10'} - dev: true - - /dedent@0.7.0: - resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dev: true - - /deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - /deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - - /define-property@0.2.5: - resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 0.1.6 - dev: true - - /define-property@1.0.0: - resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - dev: true - - /define-property@2.0.2: - resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - isobject: 3.0.1 - dev: true - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - - /denque@2.1.0: - resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} - engines: {node: '>=0.10'} - dev: false - - /depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - dev: false - - /destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dev: false - - /detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - dev: true - - /diff-sequences@29.4.3: - resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true - - /dir-glob@2.2.2: - resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==} - engines: {node: '>=4'} - dependencies: - path-type: 3.0.0 - dev: true - - /dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - - /doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - - /dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - dev: false - - /domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: false - - /domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: false - - /domutils@3.1.0: - resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - dev: false - - /dotenv@16.1.4: - resolution: {integrity: sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==} - engines: {node: '>=12'} - dev: false - - /eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - dev: true - - /ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - dev: false - - /ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - dev: false - - /electron-to-chromium@1.4.419: - resolution: {integrity: sha512-jdie3RiEgygvDTyS2sgjq71B36q2cDSBfPlwzUyuOrfYTNoYWyBxxjGJV/HAu3A2hB0Y+HesvCVkVAFoCKwCSw==} - dev: true - - /emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - dev: true - - /emoji-regex@7.0.3: - resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} - dev: false - - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - /emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true - - /encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - dev: false - - /entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - dev: false - - /error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - - /es5-ext@0.10.62: - resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} - engines: {node: '>=0.10'} - requiresBuild: true - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.3 - next-tick: 1.1.0 - dev: false - - /es6-iterator@2.0.3: - resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} - dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - es6-symbol: 3.1.3 - dev: false - - /es6-symbol@3.1.3: - resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} - dependencies: - d: 1.0.1 - ext: 1.7.0 - dev: false - - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - dev: true - - /escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - dev: false - - /escape-latex@1.2.0: - resolution: {integrity: sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==} - dev: false - - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - /escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true - - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - /eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - /eslint-scope@7.2.0: - resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - /eslint-utils@1.4.3: - resolution: {integrity: sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==} - engines: {node: '>=6'} - dependencies: - eslint-visitor-keys: 1.3.0 - dev: false - - /eslint-utils@2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - dependencies: - eslint-visitor-keys: 1.3.0 - dev: false - - /eslint-visitor-keys@1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} - dev: false - - /eslint-visitor-keys@3.4.1: - resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - /eslint@6.8.0: - resolution: {integrity: sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - hasBin: true - dependencies: - '@babel/code-frame': 7.21.4 - ajv: 6.12.6 - chalk: 2.4.2 - cross-spawn: 6.0.5 - debug: 4.3.4 - doctrine: 3.0.0 - eslint-scope: 5.1.1 - eslint-utils: 1.4.3 - eslint-visitor-keys: 1.3.0 - espree: 6.2.1 - esquery: 1.5.0 - esutils: 2.0.3 - file-entry-cache: 5.0.1 - functional-red-black-tree: 1.0.1 - glob-parent: 5.1.2 - globals: 12.4.0 - ignore: 4.0.6 - import-fresh: 3.3.0 - imurmurhash: 0.1.4 - inquirer: 7.3.3 - is-glob: 4.0.3 - js-yaml: 3.14.1 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.3.0 - lodash: 4.17.21 - minimatch: 3.1.2 - mkdirp: 0.5.6 - natural-compare: 1.4.0 - optionator: 0.8.3 - progress: 2.0.3 - regexpp: 2.0.1 - semver: 6.3.0 - strip-ansi: 5.2.0 - strip-json-comments: 3.1.1 - table: 5.4.6 - text-table: 0.2.0 - v8-compile-cache: 2.3.0 - transitivePeerDependencies: - - supports-color - dev: false - - /eslint@8.45.0: - resolution: {integrity: sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) - '@eslint-community/regexpp': 4.5.1 - '@eslint/eslintrc': 2.1.0 - '@eslint/js': 8.44.0 - '@humanwhocodes/config-array': 0.11.10 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.0 - eslint-visitor-keys: 3.4.1 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.20.0 - graphemer: 1.4.0 - ignore: 5.2.4 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - /espree@6.2.1: - resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} - engines: {node: '>=6.0.0'} - dependencies: - acorn: 7.4.1 - acorn-jsx: 5.3.2(acorn@7.4.1) - eslint-visitor-keys: 1.3.0 - dev: false - - /espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) - eslint-visitor-keys: 3.4.1 - - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - /esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - - /esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - dependencies: - estraverse: 5.3.0 - - /estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - - /estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - /etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - dev: false - - /eventemitter2@6.4.9: - resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} - dev: false - - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - dev: true - - /expand-brackets@2.1.4: - resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} - engines: {node: '>=0.10.0'} - dependencies: - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - posix-character-classes: 0.1.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /expect@29.5.0: - resolution: {integrity: sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/expect-utils': 29.5.0 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - dev: true - - /express-domain-middleware@0.1.0: - resolution: {integrity: sha512-k6UitrDPN0NbTJutuG671/wQXWFyjSbkYdKtDRHxz0VuZA1cLTMkbUIGMkmHwgQwE/XhrQyK7ZjzCFRFlaD4xw==} - dev: false - - /express-rate-limit@6.7.0(express@4.18.2): - resolution: {integrity: sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==} - engines: {node: '>= 12.9.0'} - peerDependencies: - express: ^4 || ^5 - dependencies: - express: 4.18.2 - dev: false - - /express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} - engines: {node: '>= 0.10.0'} - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.1 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.5.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.7 - qs: 6.11.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /ext@1.7.0: - resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} - dependencies: - type: 2.7.2 - dev: false - - /extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - dev: true - - /extend-shallow@3.0.2: - resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} - engines: {node: '>=0.10.0'} - dependencies: - assign-symbols: 1.0.0 - is-extendable: 1.0.1 - dev: true - - /extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: false - - /external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: false - - /extglob@2.0.4: - resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} - engines: {node: '>=0.10.0'} - dependencies: - array-unique: 0.3.2 - define-property: 1.0.0 - expand-brackets: 2.1.4 - extend-shallow: 2.0.1 - fragment-cache: 0.2.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - dev: false - - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - /fast-glob@2.2.7: - resolution: {integrity: sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==} - engines: {node: '>=4.0.0'} - dependencies: - '@mrmlnc/readdir-enhanced': 2.2.1 - '@nodelib/fs.stat': 1.1.3 - glob-parent: 3.1.0 - is-glob: 4.0.3 - merge2: 1.4.1 - micromatch: 3.1.10 - transitivePeerDependencies: - - supports-color - dev: true - - /fast-glob@3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - /fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - /fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - dependencies: - reusify: 1.0.4 - - /fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - dependencies: - bser: 2.1.1 - dev: true - - /figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - dependencies: - escape-string-regexp: 1.0.5 - dev: false - - /file-entry-cache@5.0.1: - resolution: {integrity: sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==} - engines: {node: '>=4'} - dependencies: - flat-cache: 2.0.1 - dev: false - - /file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.0.4 - - /fill-range@4.0.0: - resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-number: 3.0.0 - repeat-string: 1.6.1 - to-regex-range: 2.1.1 - dev: true - - /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - - /finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} - dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true - - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - /flat-cache@2.0.1: - resolution: {integrity: sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==} - engines: {node: '>=4'} - dependencies: - flatted: 2.0.2 - rimraf: 2.6.3 - write: 1.0.3 - dev: false - - /flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 - - /flatted@2.0.2: - resolution: {integrity: sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==} - dev: false - - /flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - - /for-in@1.0.2: - resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} - engines: {node: '>=0.10.0'} - dev: true - - /foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.0.2 - dev: true - - /forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - dev: false - - /form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /form-data@2.5.1: - resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - dev: false - - /fraction.js@4.2.0: - resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} - dev: false - - /fragment-cache@0.2.1: - resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} - engines: {node: '>=0.10.0'} - dependencies: - map-cache: 0.2.2 - dev: true - - /fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - dev: false - - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - - /functional-red-black-tree@1.0.1: - resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} - dev: false - - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-proto: 1.0.1 - has-symbols: 1.0.3 - dev: false - - /get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true - - /get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - dev: true - - /get-value@2.0.6: - resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} - engines: {node: '>=0.10.0'} - dev: true - - /getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - dependencies: - assert-plus: 1.0.0 - dev: false - - /glob-parent@3.1.0: - resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} - dependencies: - is-glob: 3.1.0 - path-dirname: 1.0.2 - dev: true - - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - - /glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - dependencies: - is-glob: 4.0.3 - - /glob-to-regexp@0.3.0: - resolution: {integrity: sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==} - dev: true - - /glob@10.2.6: - resolution: {integrity: sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.2.1 - minimatch: 9.0.1 - minipass: 6.0.2 - path-scurry: 1.9.2 - dev: true - - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - /globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true - - /globals@12.4.0: - resolution: {integrity: sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.8.1 - dev: false - - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - - /globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.2.12 - ignore: 5.2.4 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - - /globby@9.2.0: - resolution: {integrity: sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==} - engines: {node: '>=6'} - dependencies: - '@types/glob': 7.2.0 - array-union: 1.0.2 - dir-glob: 2.2.2 - fast-glob: 2.2.7 - glob: 7.2.3 - ignore: 4.0.6 - pify: 4.0.1 - slash: 2.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true - - /grapheme-splitter@1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} - dev: true - - /graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - /har-schema@2.0.0: - resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} - engines: {node: '>=4'} - dev: false - - /har-validator@5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported - dependencies: - ajv: 6.12.6 - har-schema: 2.0.0 - dev: false - - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - dev: false - - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - dev: false - - /has-value@0.3.1: - resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 0.1.4 - isobject: 2.1.0 - dev: true - - /has-value@1.0.0: - resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 1.0.0 - isobject: 3.0.1 - dev: true - - /has-values@0.1.4: - resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} - engines: {node: '>=0.10.0'} - dev: true - - /has-values@1.0.0: - resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - kind-of: 4.0.0 - dev: true - - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true - - /html-escaper@3.0.3: - resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} - dev: false - - /htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - entities: 4.5.0 - dev: false - - /http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - dev: false - - /http-signature@1.2.0: - resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} - engines: {node: '>=0.8', npm: '>=1.3.7'} - dependencies: - assert-plus: 1.0.0 - jsprim: 1.4.2 - sshpk: 1.17.0 - dev: false - - /human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true - - /iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: false - - /ignore@4.0.6: - resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} - engines: {node: '>= 4'} - - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} - engines: {node: '>= 4'} - - /import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - /import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - dev: true - - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - /inquirer@7.3.3: - resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} - engines: {node: '>=8.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - run-async: 2.4.1 - rxjs: 6.6.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - dev: false - - /ioredis@5.3.2: - resolution: {integrity: sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==} - engines: {node: '>=12.22.0'} - dependencies: - '@ioredis/commands': 1.2.0 - cluster-key-slot: 1.1.2 - debug: 4.3.4 - denque: 2.1.0 - lodash.defaults: 4.2.0 - lodash.isarguments: 3.1.0 - redis-errors: 1.2.0 - redis-parser: 3.0.0 - standard-as-callback: 2.1.0 - transitivePeerDependencies: - - supports-color - dev: false - - /ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - dev: false - - /is-accessor-descriptor@0.1.6: - resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-accessor-descriptor@1.0.0: - resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - - /is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true - - /is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: true - - /is-core-module@2.12.1: - resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} - dependencies: - has: 1.0.3 - dev: true - - /is-data-descriptor@0.1.4: - resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-data-descriptor@1.0.0: - resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - - /is-descriptor@0.1.6: - resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 0.1.6 - is-data-descriptor: 0.1.4 - kind-of: 5.1.0 - dev: true - - /is-descriptor@1.0.2: - resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 1.0.0 - is-data-descriptor: 1.0.0 - kind-of: 6.0.3 - dev: true - - /is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - dev: true - - /is-extendable@1.0.1: - resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} - engines: {node: '>=0.10.0'} - dependencies: - is-plain-object: 2.0.4 - dev: true - - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - /is-fullwidth-code-point@2.0.0: - resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} - engines: {node: '>=4'} - dev: false - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - /is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - dev: true - - /is-glob@3.1.0: - resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - - /is-number@3.0.0: - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true - - /is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - /is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - dev: false - - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true - - /is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: false - - /is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - dev: true - - /isarray@0.0.1: - resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} - dev: true - - /isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: true - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - /isobject@2.1.0: - resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} - engines: {node: '>=0.10.0'} - dependencies: - isarray: 1.0.0 - dev: true - - /isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - dev: true - - /isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - dev: false - - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} - engines: {node: '>=8'} - dev: true - - /istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - dependencies: - '@babel/core': 7.22.1 - '@babel/parser': 7.22.4 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} - engines: {node: '>=8'} - dependencies: - istanbul-lib-coverage: 3.2.0 - make-dir: 3.1.0 - supports-color: 7.2.0 - dev: true - - /istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - dependencies: - debug: 4.3.4 - istanbul-lib-coverage: 3.2.0 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-reports@3.1.5: - resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} - engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.0 - dev: true - - /jackspeak@2.2.1: - resolution: {integrity: sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==} - engines: {node: '>=14'} - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - dev: true - - /javascript-natural-sort@0.7.1: - resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} - dev: false - - /jest-changed-files@29.5.0: - resolution: {integrity: sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - execa: 5.1.1 - p-limit: 3.1.0 - dev: true - - /jest-circus@29.5.0: - resolution: {integrity: sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.5.0 - '@jest/expect': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - co: 4.6.0 - dedent: 0.7.0 - is-generator-fn: 2.1.0 - jest-each: 29.5.0 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-runtime: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 - p-limit: 3.1.0 - pretty-format: 29.5.0 - pure-rand: 6.0.2 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-cli@29.5.0(@types/node@18.16.16)(ts-node@10.9.1): - resolution: {integrity: sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.5.0(ts-node@10.9.1) - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - import-local: 3.1.0 - jest-config: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - jest-util: 29.5.0 - jest-validate: 29.5.0 - prompts: 2.4.2 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /jest-config@29.5.0(@types/node@18.16.16)(ts-node@10.9.1): - resolution: {integrity: sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==} - 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 - dependencies: - '@babel/core': 7.22.1 - '@jest/test-sequencer': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - babel-jest: 29.5.0(@babel/core@7.22.1) - chalk: 4.1.2 - ci-info: 3.8.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.5.0 - jest-environment-node: 29.5.0 - jest-get-type: 29.4.3 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-runner: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.5.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - ts-node: 10.9.1(@types/node@18.16.16)(typescript@4.9.5) - transitivePeerDependencies: - - supports-color - dev: true - - /jest-diff@29.5.0: - resolution: {integrity: sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - diff-sequences: 29.4.3 - jest-get-type: 29.4.3 - pretty-format: 29.5.0 - dev: true - - /jest-docblock@29.4.3: - resolution: {integrity: sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - detect-newline: 3.1.0 - dev: true - - /jest-each@29.5.0: - resolution: {integrity: sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - chalk: 4.1.2 - jest-get-type: 29.4.3 - jest-util: 29.5.0 - pretty-format: 29.5.0 - dev: true - - /jest-environment-node@29.5.0: - resolution: {integrity: sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.5.0 - '@jest/fake-timers': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - jest-mock: 29.5.0 - jest-util: 29.5.0 - dev: true - - /jest-get-type@29.4.3: - resolution: {integrity: sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - - /jest-haste-map@29.5.0: - resolution: {integrity: sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@types/graceful-fs': 4.1.6 - '@types/node': 18.16.16 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 29.4.3 - jest-util: 29.5.0 - jest-worker: 29.5.0 - micromatch: 4.0.5 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /jest-leak-detector@29.5.0: - resolution: {integrity: sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.4.3 - pretty-format: 29.5.0 - dev: true - - /jest-matcher-utils@29.5.0: - resolution: {integrity: sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - jest-diff: 29.5.0 - jest-get-type: 29.4.3 - pretty-format: 29.5.0 - dev: true - - /jest-message-util@29.5.0: - resolution: {integrity: sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/code-frame': 7.21.4 - '@jest/types': 29.5.0 - '@types/stack-utils': 2.0.1 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.5 - pretty-format: 29.5.0 - slash: 3.0.0 - stack-utils: 2.0.6 - dev: true - - /jest-mock@29.5.0: - resolution: {integrity: sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - jest-util: 29.5.0 - dev: true - - /jest-pnp-resolver@1.2.3(jest-resolve@29.5.0): - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - dependencies: - jest-resolve: 29.5.0 - dev: true - - /jest-regex-util@29.4.3: - resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - - /jest-resolve-dependencies@29.5.0: - resolution: {integrity: sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-regex-util: 29.4.3 - jest-snapshot: 29.5.0 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-resolve@29.5.0: - resolution: {integrity: sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.5.0) - jest-util: 29.5.0 - jest-validate: 29.5.0 - resolve: 1.22.2 - resolve.exports: 2.0.2 - slash: 3.0.0 - dev: true - - /jest-runner@29.5.0: - resolution: {integrity: sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.5.0 - '@jest/environment': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.4.3 - jest-environment-node: 29.5.0 - jest-haste-map: 29.5.0 - jest-leak-detector: 29.5.0 - jest-message-util: 29.5.0 - jest-resolve: 29.5.0 - jest-runtime: 29.5.0 - jest-util: 29.5.0 - jest-watcher: 29.5.0 - jest-worker: 29.5.0 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-runtime@29.5.0: - resolution: {integrity: sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.5.0 - '@jest/fake-timers': 29.5.0 - '@jest/globals': 29.5.0 - '@jest/source-map': 29.4.3 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - cjs-module-lexer: 1.2.2 - collect-v8-coverage: 1.0.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - jest-message-util: 29.5.0 - jest-mock: 29.5.0 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-snapshot@29.5.0: - resolution: {integrity: sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.22.1 - '@babel/generator': 7.22.3 - '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.22.1) - '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.22.1) - '@babel/traverse': 7.22.4 - '@babel/types': 7.22.4 - '@jest/expect-utils': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/babel__traverse': 7.20.1 - '@types/prettier': 2.7.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.1) - chalk: 4.1.2 - expect: 29.5.0 - graceful-fs: 4.2.11 - jest-diff: 29.5.0 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - natural-compare: 1.4.0 - pretty-format: 29.5.0 - semver: 7.5.1 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-util@29.5.0: - resolution: {integrity: sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - chalk: 4.1.2 - ci-info: 3.8.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - dev: true - - /jest-validate@29.5.0: - resolution: {integrity: sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.4.3 - leven: 3.1.0 - pretty-format: 29.5.0 - dev: true - - /jest-watcher@29.5.0: - resolution: {integrity: sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.16.16 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.5.0 - string-length: 4.0.2 - dev: true - - /jest-worker@29.5.0: - resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@types/node': 18.16.16 - jest-util: 29.5.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 - dev: true - - /jest@29.5.0(@types/node@18.16.16)(ts-node@10.9.1): - resolution: {integrity: sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.5.0(ts-node@10.9.1) - '@jest/types': 29.5.0 - import-local: 3.1.0 - jest-cli: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - - /jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - dev: false - - /jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true - - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - /json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - dev: false - - /json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - /json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: false - - /json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true - - /jsprim@1.4.2: - resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} - engines: {node: '>=0.6.0'} - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - dev: false - - /kind-of@3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of@4.0.0: - resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of@5.1.0: - resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} - engines: {node: '>=0.10.0'} - dev: true - - /kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - dev: true - - /kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true - - /kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - dev: true - - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true - - /levn@0.3.0: - resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - type-check: 0.3.2 - dev: false - - /levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - /lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true - - /linkedom@0.14.26: - resolution: {integrity: sha512-mK6TrydfFA7phrnp+1j57ycBwFI5bGSW6YXlw9acHoqF+mP/y+FooEYYyniOt5Ot57FSKB3iwmnuQ1UUyNLm5A==} - dependencies: - css-select: 5.1.0 - cssom: 0.5.0 - html-escaper: 3.0.3 - htmlparser2: 8.0.2 - uhyphen: 0.2.0 - dev: false - - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true - - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - dependencies: - p-locate: 5.0.0 - - /lodash.defaults@4.2.0: - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - dev: false - - /lodash.isarguments@3.1.0: - resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} - dev: false - - /lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - dev: true - - /lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false - - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 - dev: true - - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - - /lru-cache@9.1.2: - resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==} - engines: {node: 14 || >=16.14} - dev: true - - /make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - dependencies: - semver: 6.3.0 - dev: true - - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true - - /makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - dependencies: - tmpl: 1.0.5 - dev: true - - /map-cache@0.2.2: - resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} - engines: {node: '>=0.10.0'} - dev: true - - /map-visit@1.0.0: - resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} - engines: {node: '>=0.10.0'} - dependencies: - object-visit: 1.0.1 - dev: true - - /mathjs@11.8.0: - resolution: {integrity: sha512-I7r8HCoqUGyEiHQdeOCF2m2k9N+tcOHO3cZQ3tyJkMMBQMFqMR7dMQEboBMJAiFW2Um3PEItGPwcOc4P6KRqwg==} - engines: {node: '>= 14'} - hasBin: true - dependencies: - '@babel/runtime': 7.22.3 - complex.js: 2.1.1 - decimal.js: 10.4.3 - escape-latex: 1.2.0 - fraction.js: 4.2.0 - javascript-natural-sort: 0.7.1 - seedrandom: 3.0.5 - tiny-emitter: 2.1.0 - typed-function: 4.1.0 - dev: false - - /media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - dev: false - - /merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - dev: false - - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true - - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true - - /methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - dev: false - - /micromatch@3.1.10: - resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - braces: 2.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - extglob: 2.0.4 - fragment-cache: 0.2.1 - kind-of: 6.0.3 - nanomatch: 1.2.13 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - dev: false - - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - - /minimatch@9.0.1: - resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: true - - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - /minipass@6.0.2: - resolution: {integrity: sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==} - engines: {node: '>=16 || 14 >=14.17'} - dev: true - - /mixin-deep@1.3.2: - resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 1.0.2 - is-extendable: 1.0.1 - dev: true - - /mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - dependencies: - minimist: 1.2.8 - dev: false - - /mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: true - - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: false - - /mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: false - - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: false - - /nanomatch@1.2.13: - resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} - engines: {node: '>=0.10.0'} - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - fragment-cache: 0.2.1 - is-windows: 1.0.2 - kind-of: 6.0.3 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true - - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - /negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - dev: false - - /next-tick@1.1.0: - resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - dev: false - - /nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: false - - /node-fetch@2.6.11: - resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: false - - /node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: true - - /node-releases@2.0.12: - resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} - dev: true - - /noms@0.0.0: - resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} - dependencies: - inherits: 2.0.4 - readable-stream: 1.0.34 - dev: true - - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true - - /npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - dependencies: - path-key: 3.1.1 - dev: true - - /nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - dependencies: - boolbase: 1.0.0 - dev: false - - /oauth-sign@0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - dev: false - - /object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: false - - /object-copy@0.1.0: - resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} - engines: {node: '>=0.10.0'} - dependencies: - copy-descriptor: 0.1.1 - define-property: 0.2.5 - kind-of: 3.2.2 - dev: true - - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} - dev: false - - /object-visit@1.0.1: - resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /object.pick@1.3.0: - resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - dev: false - - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - - /optionator@0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.3.0 - prelude-ls: 1.1.2 - type-check: 0.3.2 - word-wrap: 1.2.4 - dev: false - - /optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} - dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - - /os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - dev: false - - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true - - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - dependencies: - p-limit: 3.1.0 - - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true - - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - dependencies: - callsites: 3.1.0 - - /parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - dependencies: - '@babel/code-frame': 7.21.4 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - dev: true - - /parse-srcset@1.0.2: - resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} - dev: false - - /parse5-htmlparser2-tree-adapter@7.0.0: - resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} - dependencies: - domhandler: 5.0.3 - parse5: 7.1.2 - dev: false - - /parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} - dependencies: - entities: 4.5.0 - dev: false - - /parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - dev: false - - /pascalcase@0.1.1: - resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} - engines: {node: '>=0.10.0'} - dev: true - - /path-dirname@1.0.2: - resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} - dev: true - - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - /path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - dev: false - - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true - - /path-scurry@1.9.2: - resolution: {integrity: sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - lru-cache: 9.1.2 - minipass: 6.0.2 - dev: true - - /path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - dev: false - - /path-type@3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} - dependencies: - pify: 3.0.0 - dev: true - - /path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true - - /performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - dev: false - - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true - - /pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - dev: true - - /pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - dev: true - - /pirates@4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} - engines: {node: '>= 6'} - dev: true - - /pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - dev: true - - /posix-character-classes@0.1.1: - resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} - engines: {node: '>=0.10.0'} - dev: true - - /postcss@8.4.24: - resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.6 - picocolors: 1.0.0 - source-map-js: 1.0.2 - dev: false - - /prelude-ls@1.1.2: - resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} - engines: {node: '>= 0.8.0'} - dev: false - - /prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - /prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true - - /pretty-format@29.5.0: - resolution: {integrity: sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.4.3 - ansi-styles: 5.2.0 - react-is: 18.2.0 - dev: true - - /prisma-json-types-generator@2.4.0: - resolution: {integrity: sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg==} - engines: {node: '>=14.0'} - hasBin: true - dependencies: - '@prisma/generator-helper': 4.15.0 - tslib: 2.5.3 - transitivePeerDependencies: - - supports-color - dev: true - - /prisma@5.0.0: - resolution: {integrity: sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA==} - engines: {node: '>=16.13'} - hasBin: true - requiresBuild: true - dependencies: - '@prisma/engines': 5.0.0 - - /process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true - - /progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - dev: false - - /prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - dev: true - - /proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - dev: false - - /psl@1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: false - - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} - engines: {node: '>=6'} - - /pure-rand@6.0.2: - resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} - dev: true - - /qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - dependencies: - side-channel: 1.0.4 - dev: false - - /qs@6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} - dev: false - - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - /range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - dev: false - - /rate-limit-redis@3.0.2(express-rate-limit@6.7.0): - resolution: {integrity: sha512-4SBK6AzIr9PKkCF4HmSDcJH2O2KKMF3fZEcsbNMXyaL5I9d6X71uOreUldFRiyrRyP+qkQrTxzJ38ZKKN+sScw==} - engines: {node: '>= 14.5.0'} - peerDependencies: - express-rate-limit: ^6 - dependencies: - express-rate-limit: 6.7.0(express@4.18.2) - dev: false - - /raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: false - - /raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: false - - /react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true - - /readable-stream@1.0.34: - resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 0.0.1 - string_decoder: 0.10.31 - dev: true - - /readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - dev: true - - /redis-errors@1.2.0: - resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} - engines: {node: '>=4'} - dev: false - - /redis-parser@3.0.0: - resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} - engines: {node: '>=4'} - dependencies: - redis-errors: 1.2.0 - dev: false - - /regenerator-runtime@0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - dev: false - - /regex-not@1.0.2: - resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 3.0.2 - safe-regex: 1.1.0 - dev: true - - /regexpp@2.0.1: - resolution: {integrity: sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==} - engines: {node: '>=6.5.0'} - dev: false - - /regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - dev: false - - /repeat-element@1.1.4: - resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} - engines: {node: '>=0.10.0'} - dev: true - - /repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - dev: true - - /request-promise-core@1.1.4(request@2.88.2): - resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==} - engines: {node: '>=0.10.0'} - peerDependencies: - request: ^2.34 - dependencies: - lodash: 4.17.21 - request: 2.88.2 - dev: false - - /request-promise@4.2.6(request@2.88.2): - resolution: {integrity: sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==} - engines: {node: '>=0.10.0'} - deprecated: request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 - peerDependencies: - request: ^2.34 - dependencies: - bluebird: 3.7.2 - request: 2.88.2 - request-promise-core: 1.1.4(request@2.88.2) - stealthy-require: 1.1.1 - tough-cookie: 2.5.0 - dev: false - - /request@2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - dependencies: - aws-sign2: 0.7.0 - aws4: 1.12.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.3 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 - dev: false - - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - dependencies: - resolve-from: 5.0.0 - dev: true - - /resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - /resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true - - /resolve-url@0.2.1: - resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} - deprecated: https://github.com/lydell/resolve-url#deprecated - dev: true - - /resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - dev: true - - /resolve@1.22.2: - resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} - hasBin: true - dependencies: - is-core-module: 2.12.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: false - - /ret@0.1.15: - resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} - engines: {node: '>=0.12'} - dev: true - - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - /rimraf@2.6.3: - resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: false - - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - - /rimraf@5.0.1: - resolution: {integrity: sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==} - engines: {node: '>=14'} - hasBin: true - dependencies: - glob: 10.2.6 - dev: true - - /run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - dev: false - - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - - /rxjs@6.6.7: - resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} - engines: {npm: '>=2.0.0'} - dependencies: - tslib: 1.14.1 - dev: false - - /safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true - - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: false - - /safe-regex@1.1.0: - resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} - dependencies: - ret: 0.1.15 - dev: true - - /safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: false - - /sanitize-html@2.10.0: - resolution: {integrity: sha512-JqdovUd81dG4k87vZt6uA6YhDfWkUGruUu/aPmXLxXi45gZExnt9Bnw/qeQU8oGf82vPyaE0vO4aH0PbobB9JQ==} - dependencies: - deepmerge: 4.3.1 - escape-string-regexp: 4.0.0 - htmlparser2: 8.0.2 - is-plain-object: 5.0.0 - parse-srcset: 1.0.2 - postcss: 8.4.24 - dev: false - - /seedrandom@3.0.5: - resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==} - dev: false - - /semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - dev: false - - /semver@6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - - /semver@7.5.1: - resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - - /send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - dev: false - - /serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} - dependencies: - encodeurl: 1.0.2 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.18.0 - transitivePeerDependencies: - - supports-color - dev: false - - /set-value@2.0.1: - resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-extendable: 0.1.1 - is-plain-object: 2.0.4 - split-string: 3.1.0 - dev: true - - /setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - dev: false - - /shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} - dependencies: - shebang-regex: 1.0.0 - dev: false - - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - - /shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - dev: false - - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 - dev: false - - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - /signal-exit@4.0.2: - resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} - engines: {node: '>=14'} - dev: true - - /sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true - - /slash@2.0.0: - resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} - engines: {node: '>=6'} - dev: true - - /slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true - - /slice-ansi@2.1.0: - resolution: {integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==} - engines: {node: '>=6'} - dependencies: - ansi-styles: 3.2.1 - astral-regex: 1.0.0 - is-fullwidth-code-point: 2.0.0 - dev: false - - /snapdragon-node@2.1.1: - resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 1.0.0 - isobject: 3.0.1 - snapdragon-util: 3.0.1 - dev: true - - /snapdragon-util@3.0.1: - resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /snapdragon@0.8.2: - resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} - engines: {node: '>=0.10.0'} - dependencies: - base: 0.11.2 - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - map-cache: 0.2.2 - source-map: 0.5.7 - source-map-resolve: 0.5.3 - use: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} - engines: {node: '>=0.10.0'} - dev: false - - /source-map-resolve@0.5.3: - resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} - deprecated: See https://github.com/lydell/source-map-resolve#deprecated - dependencies: - atob: 2.1.2 - decode-uri-component: 0.2.2 - resolve-url: 0.2.1 - source-map-url: 0.4.1 - urix: 0.1.0 - dev: true - - /source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map-url@0.4.1: - resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} - deprecated: See https://github.com/lydell/source-map-url#deprecated - dev: true - - /source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - dev: true - - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true - - /split-string@3.1.0: - resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 3.0.2 - dev: true - - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - /sshpk@1.17.0: - resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - dev: false - - /stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - dependencies: - escape-string-regexp: 2.0.0 - dev: true - - /standard-as-callback@2.1.0: - resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - dev: false - - /static-extend@0.1.2: - resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 0.2.5 - object-copy: 0.1.0 - dev: true - - /statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - dev: false - - /stealthy-require@1.1.1: - resolution: {integrity: sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==} - engines: {node: '>=0.10.0'} - dev: false - - /string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - dev: true - - /string-width@3.1.0: - resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} - engines: {node: '>=6'} - dependencies: - emoji-regex: 7.0.3 - is-fullwidth-code-point: 2.0.0 - strip-ansi: 5.2.0 - dev: false - - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - /string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - dev: true - - /string_decoder@0.10.31: - resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} - dev: true - - /string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - dependencies: - safe-buffer: 5.1.2 - dev: true - - /strip-ansi@5.2.0: - resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} - engines: {node: '>=6'} - dependencies: - ansi-regex: 4.1.1 - dev: false - - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - - /strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - dependencies: - ansi-regex: 6.0.1 - dev: true - - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true - - /strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true - - /strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true - - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - - /supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - dependencies: - has-flag: 4.0.0 - dev: true - - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true - - /table@5.4.6: - resolution: {integrity: sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==} - engines: {node: '>=6.0.0'} - dependencies: - ajv: 6.12.6 - lodash: 4.17.21 - slice-ansi: 2.1.0 - string-width: 3.1.0 - dev: false - - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - dev: true - - /text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - /through2@2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - dependencies: - readable-stream: 2.3.8 - xtend: 4.0.2 - dev: true - - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: false - - /tiny-emitter@2.1.0: - resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} - dev: false - - /tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - dev: false - - /tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: true - - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true - - /to-object-path@0.3.0: - resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /to-regex-range@2.1.1: - resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - repeat-string: 1.6.1 - dev: true - - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - - /to-regex@3.0.2: - resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 2.0.2 - extend-shallow: 3.0.2 - regex-not: 1.0.2 - safe-regex: 1.1.0 - dev: true - - /toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - dev: false - - /tough-cookie@2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} - dependencies: - psl: 1.9.0 - punycode: 2.3.0 - dev: false - - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false - - /ts-jest@29.1.0(@babel/core@7.22.1)(jest@29.5.0)(typescript@4.9.5): - resolution: {integrity: sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 - esbuild: '*' - jest: ^29.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - dependencies: - '@babel/core': 7.22.1 - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - jest: 29.5.0(@types/node@18.16.16)(ts-node@10.9.1) - jest-util: 29.5.0 - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.5.1 - typescript: 4.9.5 - yargs-parser: 21.1.1 - dev: true - - /ts-node@10.9.1(@types/node@18.16.16)(typescript@4.9.5): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - 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 - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 18.16.16 - acorn: 8.8.2 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.9.5 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 - dev: true - - /tscpaths@0.0.9: - resolution: {integrity: sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w==} - hasBin: true - dependencies: - commander: 2.20.3 - globby: 9.2.0 - transitivePeerDependencies: - - supports-color - dev: true - - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - - /tslib@2.5.3: - resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} - dev: true - - /tsutils@3.21.0(typescript@3.9.10): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 3.9.10 - dev: false - - /tsutils@3.21.0(typescript@4.9.5): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 4.9.5 - dev: true - - /tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - dev: false - - /type-check@0.3.2: - resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - dev: false - - /type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - - /type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - dev: true - - /type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - - /type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - dev: false - - /type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - dev: false - - /type@1.2.0: - resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} - dev: false - - /type@2.7.2: - resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} - dev: false - - /typed-function@4.1.0: - resolution: {integrity: sha512-DGwUl6cioBW5gw2L+6SMupGwH/kZOqivy17E4nsh1JI9fKF87orMmlQx3KISQPmg3sfnOUGlwVkroosvgddrlg==} - engines: {node: '>= 14'} - dev: false - - /typescript@3.9.10: - resolution: {integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: false - - /typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true - - /uhyphen@0.2.0: - resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==} - dev: false - - /union-value@1.0.1: - resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - get-value: 2.0.6 - is-extendable: 0.1.1 - set-value: 2.0.1 - dev: true - - /unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - dev: false - - /unset-value@1.0.0: - resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} - engines: {node: '>=0.10.0'} - dependencies: - has-value: 0.3.1 - isobject: 3.0.1 - dev: true - - /untildify@4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - dev: true - - /update-browserslist-db@1.0.11(browserslist@4.21.7): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.21.7 - escalade: 3.1.1 - picocolors: 1.0.0 - dev: true - - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - dependencies: - punycode: 2.3.0 - - /urix@0.1.0: - resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} - deprecated: Please see https://github.com/lydell/urix#deprecated - dev: true - - /use@3.1.1: - resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} - engines: {node: '>=0.10.0'} - dev: true - - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true - - /utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - dev: false - - /uuid@3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - dev: false - - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true - - /v8-compile-cache@2.3.0: - resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} - dev: false - - /v8-to-istanbul@9.1.0: - resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} - engines: {node: '>=10.12.0'} - dependencies: - '@jridgewell/trace-mapping': 0.3.18 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 - dev: true - - /vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - dev: false - - /verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - dev: false - - /walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - dependencies: - makeerror: 1.0.12 - dev: true - - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false - - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: false - - /which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: false - - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - - /word-wrap@1.2.4: - resolution: {integrity: sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==} - engines: {node: '>=0.10.0'} - dev: false - - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - dev: true - - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - /write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - dev: true - - /write@1.0.3: - resolution: {integrity: sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==} - engines: {node: '>=4'} - dependencies: - mkdirp: 0.5.6 - dev: false - - /xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - dev: true - - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true - - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true - - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - /yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - dev: true - - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true - - /yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - dev: true - - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - 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.8 - yargs-parser: 21.1.1 - dev: true - - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true - - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} diff --git a/anify-auth/prisma/schema.prisma b/anify-auth/prisma/schema.prisma deleted file mode 100644 index cc8081a..0000000 --- a/anify-auth/prisma/schema.prisma +++ /dev/null @@ -1,84 +0,0 @@ -generator client { - provider = "prisma-client-js" - previewFeatures = ["orderByNulls", "clientExtensions", "postgresqlExtensions", "filteredRelationCount"] -} - -datasource db { - provider = "sqlite" - url = env("DATABASE_URL") -} - -generator json { - provider = "prisma-json-types-generator" -} - -model User { - id String @id @default(uuid()) - username String @unique - password String - salt String - simklId String? - anilistId String? - malId String? - lists List[] - settings UserSettings? -} - -model List { - id String @id @default(uuid()) - name String - type String - userId String - user User @relation(fields: [userId], references: [id]) - entries Entry[] -} - -model Entry { - id String @id @default(uuid()) - listId String - list List @relation(fields: [listId], references: [id]) - status String - score Int - progress Int - progressVolumes Int - repeat Int - priority Int - private Boolean - mappings String - notes String? - hiddenFromStatusLists Boolean - advancedScores AdvancedScores? - startedAt DateTime? - completedAt DateTime? - updatedAt DateTime? - createdAt DateTime? -} - -model AdvancedScores { - id String @id @default(uuid()) - entryId String @unique - entry Entry @relation(fields: [entryId], references: [id]) - story Int - characters Int - visuals Int - audio Int - enjoyment Int - updatedAt DateTime? - createdAt DateTime? -} - -model UserSettings { - id String @id @default(uuid()) - userId String @unique - user User @relation(fields: [userId], references: [id]) - autoSkip Boolean @default(false) - autoFullscreen Boolean @default(false) - autoNext Boolean @default(false) - fontSize String @default("1rem 1.5rem") - fontWidth String @default("200") - titleLanguage String @default("english") - displayAdultContent Boolean @default(false) - airingNotifications Boolean @default(false) - updatedAt DateTime? - createdAt DateTime? -} \ No newline at end of file diff --git a/anify-auth/src/database/impl/get.ts b/anify-auth/src/database/impl/get.ts new file mode 100644 index 0000000..7730c78 --- /dev/null +++ b/anify-auth/src/database/impl/get.ts @@ -0,0 +1,8 @@ +import { db } from ".."; + +export const get = async (id: string) => { + const query = ` + SELECT * FROM User WHERE id = $id; + `; + return await db.query(query).get({ $id: id }); +}; diff --git a/anify-auth/src/database/impl/insert.ts b/anify-auth/src/database/impl/insert.ts new file mode 100644 index 0000000..2472bbb --- /dev/null +++ b/anify-auth/src/database/impl/insert.ts @@ -0,0 +1,29 @@ +import { db } from ".."; +import { generateUUID } from "../../helper"; +import { IDs } from "../../types"; + +export const insertUser = async (ids: IDs, username: string, password: string, salt: string) => { + // Check if user already exists + const user = await db + .query( + ` + SELECT * FROM User WHERE username = $username; + `, + ) + .get({ $username: username }); + if (user) return null; + + const query = ` + INSERT INTO User (id, username, password, salt, anilistId, malId, simklId) VALUES ($id, $username, $password, $salt, $anilistId, $malId, $simklId); + `; + + await db.query(query).run({ + $id: generateUUID(), + $username: username, + $password: password, + $salt: salt, + $anilistId: ids.anilistId ?? "", + $malId: ids.malId ?? "", + $simklId: ids.simklId ?? "", + }); +}; diff --git a/anify-auth/src/database/impl/login.ts b/anify-auth/src/database/impl/login.ts new file mode 100644 index 0000000..ce92ea2 --- /dev/null +++ b/anify-auth/src/database/impl/login.ts @@ -0,0 +1,16 @@ +import { db } from ".."; +import { dehashPassword } from "../../helper"; + +export const login = async (username: string, password: string) => { + const query = ` + SELECT * FROM User WHERE username = $username; + `; + + const user = await db.query(query).get({ $username: username }); + if (!user) return null; + + const valid = await dehashPassword(password, (user as any).password); + if (!valid) return null; + + return user; +}; diff --git a/anify-auth/src/database/impl/update.ts b/anify-auth/src/database/impl/update.ts new file mode 100644 index 0000000..7558832 --- /dev/null +++ b/anify-auth/src/database/impl/update.ts @@ -0,0 +1,17 @@ +import { db } from ".."; +import { IDs } from "../../types"; + +export const updateUser = async (id: string, ids: IDs) => { + const query = ` + UPDATE User + SET anilistId = $anilistId, malId = $malId, simklId = $simklId + WHERE id = $id; + `; + + return await db.query(query).run({ + $id: id, + $anilistId: ids.anilistId ?? "", + $malId: ids.malId ?? "", + $simklId: ids.simklId ?? "", + }); +}; diff --git a/anify-auth/src/database/index.ts b/anify-auth/src/database/index.ts new file mode 100644 index 0000000..e6b4739 --- /dev/null +++ b/anify-auth/src/database/index.ts @@ -0,0 +1,97 @@ +import { Database } from "bun:sqlite"; + +export const db = new Database("db.sqlite"); + +export const init = async () => { + const list = ` + CREATE TABLE IF NOT EXISTS "List" ( + "id" TEXT NOT NULL PRIMARY KEY, + "name" TEXT NOT NULL, + "type" TEXT NOT NULL, + "userId" TEXT NOT NULL, + CONSTRAINT "List_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE + ); + `; + const entry = ` + CREATE TABLE IF NOT EXISTS "Entry" ( + "id" TEXT NOT NULL PRIMARY KEY, + "listId" TEXT NOT NULL, + "status" TEXT NOT NULL, + "score" INTEGER NOT NULL, + "progress" INTEGER NOT NULL, + "progressVolumes" INTEGER NOT NULL, + "repeat" INTEGER NOT NULL, + "priority" INTEGER NOT NULL, + "private" BOOLEAN NOT NULL, + "mappings" TEXT NOT NULL, + "notes" TEXT, + "hiddenFromStatusLists" BOOLEAN NOT NULL, + "startedAt" DATETIME, + "completedAt" DATETIME, + "updatedAt" DATETIME, + "createdAt" DATETIME, + CONSTRAINT "Entry_listId_fkey" FOREIGN KEY ("listId") REFERENCES "List" ("id") ON DELETE RESTRICT ON UPDATE CASCADE + ); + `; + const advancedScores = ` + CREATE TABLE IF NOT EXISTS "AdvancedScores" ( + "id" TEXT NOT NULL PRIMARY KEY, + "entryId" TEXT NOT NULL, + "story" INTEGER NOT NULL, + "characters" INTEGER NOT NULL, + "visuals" INTEGER NOT NULL, + "audio" INTEGER NOT NULL, + "enjoyment" INTEGER NOT NULL, + "updatedAt" DATETIME, + "createdAt" DATETIME, + CONSTRAINT "AdvancedScores_entryId_fkey" FOREIGN KEY ("entryId") REFERENCES "Entry" ("id") ON DELETE RESTRICT ON UPDATE CASCADE + ); + `; + const userSettings = ` + CREATE TABLE IF NOT EXISTS "UserSettings" ( + "id" TEXT NOT NULL PRIMARY KEY, + "userId" TEXT NOT NULL, + "autoSkip" BOOLEAN NOT NULL DEFAULT false, + "autoFullscreen" BOOLEAN NOT NULL DEFAULT false, + "autoNext" BOOLEAN NOT NULL DEFAULT false, + "fontSize" TEXT NOT NULL DEFAULT '1rem 1.5rem', + "fontWidth" TEXT NOT NULL DEFAULT '200', + "titleLanguage" TEXT NOT NULL DEFAULT 'english', + "displayAdultContent" BOOLEAN NOT NULL DEFAULT false, + "airingNotifications" BOOLEAN NOT NULL DEFAULT false, + "updatedAt" DATETIME, + "createdAt" DATETIME, + CONSTRAINT "UserSettings_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE + ); + `; + const scoreKey = `CREATE UNIQUE INDEX "AdvancedScores_entryId_key" ON "AdvancedScores"("entryId");`; + const userSettingsKey = `CREATE UNIQUE INDEX "UserSettings_userId_key" ON "UserSettings"("userId");`; + const user = ` + CREATE TABLE IF NOT EXISTS "User" ( + "id" TEXT NOT NULL PRIMARY KEY, + "username" TEXT NOT NULL, + "password" TEXT NOT NULL, + "salt" TEXT NOT NULL, + "simklId" TEXT, + "anilistId" TEXT, + "malId" TEXT + ); + `; + const userKey = `CREATE UNIQUE INDEX "User_username_key" ON "User"("username");`; + + await db.query(list).run(); + await db.query(entry).run(); + await db.query(advancedScores).run(); + await db.query(userSettings).run(); + + const scoreKeyExists = await db.query(`SELECT name FROM sqlite_master WHERE type='index' AND name='AdvancedScores_entryId_key';`).get(); + if (!scoreKeyExists) await db.query(scoreKey).run(); + + const userSettingsKeyExists = await db.query(`SELECT name FROM sqlite_master WHERE type='index' AND name='UserSettings_userId_key';`).get(); + if (!userSettingsKeyExists) await db.query(userSettingsKey).run(); + + await db.query(user).run(); + + const userKeyExists = await db.query(`SELECT name FROM sqlite_master WHERE type='index' AND name='User_username_key';`).get(); + if (!userKeyExists) await db.query(userKey).run(); +}; diff --git a/anify-auth/src/env.ts b/anify-auth/src/env.ts index fdfb9d2..8dedf5d 100644 --- a/anify-auth/src/env.ts +++ b/anify-auth/src/env.ts @@ -1,16 +1,13 @@ -// All environment variables. export const env = { - PORT: Number(process.env.PORT) || 3000, - BACKEND_URL: process.env.BACKEND_URL, - FRONTEND_URL: process.env.FRONTEND_URL, - BACKEND_KEY: process.env.BACKEND_KEY ?? "", - DATABASE_URL: process.env.DATABASE_URL, + PORT: Number(process.env.PORT) || 3606, + DATABASE_URL: process.env.DATABASE_URL ?? "./db.sqlite", + FRONTEND_URL: process.env.FRONTEND_URL ?? "http://localhost:3000", REDIS_URL: process.env.REDIS_URL, REDIS_CACHE_TIME: Number(process.env.REDIS_CACHE_TIME) || 60 * 60 * 24 * 7, }; export const providerEnv = { - PUBLIC_URL: process.env.PUBLIC_URL || `http://localhost:${process.env.PORT || 3000}`, + PUBLIC_URL: process.env.PUBLIC_URL || `http://localhost:${process.env.PORT || 3606}`, ANILIST_CLIENT_ID: process.env.ANILIST_CLIENT_ID ?? "", ANILIST_CLIENT_SECRET: process.env.ANILIST_CLIENT_SECRET ?? "", MAL_CLIENT_ID: process.env.MAL_CLIENT_ID ?? "", diff --git a/anify-auth/src/helper/index.ts b/anify-auth/src/helper/index.ts index abfc173..4b09ddc 100644 --- a/anify-auth/src/helper/index.ts +++ b/anify-auth/src/helper/index.ts @@ -1,4 +1,4 @@ -import bcrypt from "bcrypt"; +import * as bcrypt from "bcryptjs"; export function generateUUID(): string { const pattern = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"; @@ -9,17 +9,17 @@ export function generateUUID(): string { }); } -export function isValidDate(d) { +export function isValidDate(d: any) { return d instanceof Date && !isNaN(Number(d)); } export async function hashPassword(password: string): Promise<{ password: string; salt: string }> { - const saltRounds = 10; - const salt = await bcrypt.genSalt(saltRounds); + const salt = await bcrypt.genSalt(10); const hash = await bcrypt.hash(password, salt); - return { password: hash, salt }; + + return { password: hash, salt: salt }; } -export async function dehashPassword(password: string, hash: string): Promise { +export async function dehashPassword(password: string, hash: string): Promise { return await bcrypt.compare(password, hash); } diff --git a/anify-auth/src/index.ts b/anify-auth/src/index.ts index 4045fa5..025be0f 100644 --- a/anify-auth/src/index.ts +++ b/anify-auth/src/index.ts @@ -1,154 +1,6 @@ -import dotenv from "dotenv"; -dotenv.config(); +import { init } from "./database"; +import { start } from "./server"; -import { env } from "./env"; -import { AUTH_PROVIDERS, routes } from "./providers"; -import { Redis } from "ioredis"; -import colors from "colors"; -import Fastify from "fastify"; -import FastifyCors from "@fastify/cors"; -import { fetchSettings, fetchUser, insertUser, login, updateSettings, updateUser } from "./lib/impl/database"; -import { Settings } from "./lib/types"; -import { hashPassword } from "./helper"; - -export let redis = new Redis(env.REDIS_URL as string); - -if (!env.REDIS_URL) { - console.log(colors.yellow("No Redis URL provided. Caching will be disabled.")); - redis = { - get: async () => null, - set: (): Promise<"OK"> => Promise.resolve("OK"), - on: () => Redis.prototype, - keys: async () => [], - connect: async () => void 0, - call: async () => void 0, - } as any; -} - -(async () => { - const fastify = Fastify({ - maxParamLength: 1000, - }); - - await fastify.register(FastifyCors, { - origin: "*", - methods: "GET", - }); - - routes.map(async (x) => await fastify.register(x.controller, { prefix: x.prefix })); - - try { - fastify.get("/", (_, reply) => { - reply.status(200).send("Welcome to Anify's authentication API. Please view https://docs.anify.tv for more information."); - }); - - fastify.get("/providers", (_, reply) => { - reply.status(200).send( - AUTH_PROVIDERS.map((x) => { - return { - id: x.id, - url: x.url, - name: x.name, - icon: x.icon, - oauth: x.oauthURL, - }; - }) - ); - }); - - fastify.get("/user", async (request, reply) => { - const { id } = request.query as { id: string }; - if (!id) return reply.status(400).send({ error: "No user ID provided." }); - - const data = await fetchUser(id); - return reply.status(200).send(data); - }); - - fastify.post("/user", async (request, reply) => { - const { id } = request.body as { id: string }; - if (!id) return reply.status(400).send({ error: "No user ID provided." }); - - const data = await fetchUser(id); - return reply.status(200).send(data); - }); - - fastify.post("/create-user", async (request, reply) => { - const { username, password, anilistId, malId, simklId } = request.body as { username: string; password: string; anilistId?: string; malId?: string; simklId?: string }; - - if (!username) return reply.status(400).send({ error: "No username provided." }); - if (!password) return reply.status(400).send({ error: "No password provided." }); - - const passData = await hashPassword(password); - - const data = await insertUser({ anilistId, malId, simklId }, username, passData.password, passData.salt); - if (!data) return reply.status(400).send({ error: "User already exists." }); - - return reply.status(200).send(data); - }); - - fastify.post("/login", async (request, reply) => { - const { username, password } = request.body as { username: string; password: string }; - - if (!username) return reply.status(400).send({ error: "No username provided." }); - if (!password) return reply.status(400).send({ error: "No password provided." }); - - const data = await login(username, password); - if (!data) return reply.status(400).send({ error: "Invalid username or password." }); - - return reply.status(200).send(data); - }); - - fastify.post("/update-user", async (request, reply) => { - const { id, anilistId, malId, simklId } = request.body as { id: string; anilistId?: string; malId?: string; simklId?: string }; - if (!id) return reply.status(400).send({ error: "No user ID provided." }); - - const data = await updateUser(id, { anilistId, malId, simklId }); - return reply.status(200).send(data); - }); - - fastify.get("/settings", async (request, reply) => { - const { id } = request.query as { id: string }; - if (!id) return reply.status(400).send({ error: "No user ID provided." }); - - const settings = await redis.get(`settings:${id}`); - if (!settings) return reply.status(404).send({ error: "Settings not found." }); - - const data = await fetchSettings(id); - await redis.set(`settings:${id}`, JSON.stringify(data), "EX", 60 * 60 * 24 * 7); - return reply.status(200).send(data); - }); - - fastify.post("/settings", async (request, reply) => { - const { id } = request.body as { id: string }; - if (!id) return reply.status(400).send({ error: "No user ID provided." }); - - const settings = await redis.get(`settings:${id}`); - if (!settings) return reply.status(404).send({ error: "Settings not found." }); - - const data = await fetchSettings(id); - await redis.set(`settings:${id}`, JSON.stringify(data), "EX", 60 * 60 * 24 * 7); - return reply.status(200).send(data); - }); - - fastify.post("/update-settings", async (request, reply) => { - const { id, settings } = request.body as { id: string; settings: Settings }; - if (!id) return reply.status(400).send({ error: "No user ID provided." }); - if (!settings) return reply.status(400).send({ error: "No settings provided." }); - - const data = await updateSettings(id, settings); - return reply.status(200).send(data); - }); - - fastify.get("*", (_, reply) => { - reply.status(404).send({ error: "Page not found." }); - }); - - fastify.listen({ port: env.PORT }, (e, address) => { - if (e) throw e; - console.log(colors.blue(`Server is now listening on ${address}`)); - }); - } catch (err) { - fastify.log.error(err); - process.exit(1); - } -})().catch(console.error); +init().then(async () => { + await start(); +}); diff --git a/anify-auth/src/lib/impl/database.ts b/anify-auth/src/lib/impl/database.ts deleted file mode 100644 index 11e36c4..0000000 --- a/anify-auth/src/lib/impl/database.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { PrismaClient } from "@prisma/client"; -import { Settings } from "../types"; -import { dehashPassword } from "@/src/helper"; - -export const prisma = new PrismaClient(); - -export const insertUser = async (ids: IDs, username: string, password: string, salt: string) => { - // Check if user already exists - if ( - await prisma.user.findUnique({ - where: { - username, - }, - }) - ) { - return null; - } - - return await prisma.user.create({ - data: { - username, - password, - salt, - anilistId: ids.anilistId, - malId: ids.malId, - simklId: ids.simklId, - settings: { - create: { - autoSkip: false, - autoNext: false, - autoFullscreen: false, - airingNotifications: false, - displayAdultContent: false, - titleLanguage: "english", - fontSize: "1rem 1.5rem", - fontWidth: "200", - updatedAt: new Date(Date.now()), - createdAt: new Date(Date.now()), - }, - }, - }, - }); -}; - -export const updateUser = async (id: string, ids: IDs) => { - return await prisma.user.update({ - where: { - id, - }, - data: { - anilistId: ids.anilistId, - malId: ids.malId, - simklId: ids.simklId, - }, - }); -}; - -export const fetchUser = async (id: string) => { - return await prisma.user.findUnique({ - where: { - id, - }, - select: { - id: true, - anilistId: true, - malId: true, - lists: true, - settings: true, - username: true, - simklId: true, - password: false, - salt: false, - }, - }); -}; - -export const login = async (username: string, password: string) => { - const user = await prisma.user.findUnique({ - where: { - username, - }, - }); - - if (!user) return null; - - const valid = await dehashPassword(password, user.password); - if (!valid) return null; - - // Remove password and salt from user object - return await prisma.user.findUnique({ - where: { - username, - }, - select: { - id: true, - anilistId: true, - malId: true, - lists: true, - settings: true, - username: true, - simklId: true, - password: false, - salt: false, - }, - }); -}; - -export const fetchSettings = async (id: string) => { - return await prisma.userSettings.findUnique({ - where: { - userId: id, - }, - }); -}; - -export const updateSettings = async ( - id: string, - settings: Settings = { - autoSkip: false, - autoNext: false, - autoFullscreen: false, - fontSize: "1rem 1.5rem", - fontWidth: "200", - titleLanguage: "english", - displayAdultContent: false, - airingNotifications: false, - } -) => { - return await prisma.userSettings.update({ - where: { - userId: id, - }, - data: { - autoSkip: settings.autoSkip, - autoNext: settings.autoNext, - autoFullscreen: settings.autoFullscreen, - fontSize: settings.fontSize, - fontWidth: settings.fontWidth, - titleLanguage: settings.titleLanguage, - displayAdultContent: settings.displayAdultContent, - airingNotifications: settings.airingNotifications, - updatedAt: new Date(Date.now()), - }, - }); -}; - -interface IDs { - anilistId?: string; - malId?: string; - simklId?: string; -} diff --git a/anify-auth/src/lib/impl/sync.ts b/anify-auth/src/lib/impl/sync.ts deleted file mode 100644 index 33de031..0000000 --- a/anify-auth/src/lib/impl/sync.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { AUTH_PROVIDERS, authProviders } from "@/src/providers"; -import { prisma } from "./database"; -import { env } from "@/src/env"; -import { Entry, ListData } from "@/src/providers/impl"; - -export const sync = async (userId: string, accessTokens: AccessTokens) => { - const user = await prisma.user.findUnique({ - where: { - id: userId, - }, - }); - - if (!user) return; - - console.log("Syncing user " + user.id); - - const { simklId, anilistId, malId } = user; - - const listData: ListData[] = []; - - if (anilistId) { - console.log("Syncing AniList profile for " + user.id); - - const lists = await authProviders.anilist.fetchList(String(anilistId), accessTokens.anilist ?? ""); - - for (const list of lists ?? []) { - for (const entry of list.entries) { - const aniListMapping = entry.mappings.find((mapping) => mapping.providerId === "anilist"); - const anilistId = aniListMapping ? aniListMapping.id : ""; - const info = await (await fetch(`${env.BACKEND_URL}/info?id=${anilistId}&apikey=${env.BACKEND_KEY}`)).json(); - if (!info || !info?.mappings) continue; - - const mappings = info.mappings.concat([ - { - id: info.id, - providerId: "anilist", - }, - ]); - - mappings.push({ - id: anilistId, - providerId: "anilist", - }); - - entry.mappings = mappings; - - for (const provider of AUTH_PROVIDERS) { - if (provider.id === "anilist") continue; - - await provider.updateEntry(userId, accessTokens[provider.id], entry); - console.log("Updated entry " + entry.id); - } - /* - await prisma.entry.upsert({ - where: { - id: entry.id - }, - create: { - id: entry.id, - title: entry.title, - type: entry.type, - status: entry.status, - progress: entry.progress, - score: entry.score, - startedAt: entry.startedAt, - completedAt: entry.completedAt, - updatedAt: entry.updatedAt, - user: { - connect: { - id: userId - } - } - }, - update: { - title: entry.title, - type: entry.type, - status: entry.status, - progress: entry.progress, - score: entry.score, - startedAt: entry.startedAt, - completedAt: entry.completedAt, - updatedAt: entry.updatedAt - } - }); - */ - } - } - } - - if (malId) { - console.log("Syncing MAL profile for " + user.id); - - const lists = await authProviders.mal.fetchList(String(malId), accessTokens.mal ?? ""); - - for (const list of lists ?? []) { - for (const entry of list.entries) { - const malMapping = entry.mappings.find((mapping) => mapping.providerId === "mal"); - const malId = malMapping ? malMapping.id : ""; - const info = await (await fetch(`${env.BACKEND_URL}/media?id=${malId}&providerId=${"mal"}&apikey=${env.BACKEND_KEY}`)).json(); - if (!info || !info?.mappings) continue; - - const mappings = info.mappings.concat([ - { - id: info.id, - providerId: "anilist", - }, - ]); - - entry.mappings = mappings; - - for (const provider of AUTH_PROVIDERS) { - if (provider.id === "mal") continue; - - await provider.updateEntry(userId, accessTokens[provider.id], entry); - console.log("Updated entry " + entry.id); - } - } - } - } -}; - -interface AccessTokens { - anilist?: string; - simkl?: string; - mal?: string; -} diff --git a/anify-auth/src/lib/index.ts b/anify-auth/src/lib/index.ts deleted file mode 100644 index e69de29..0000000 diff --git a/anify-auth/src/lib/types.ts b/anify-auth/src/lib/types.ts deleted file mode 100644 index 3c87295..0000000 --- a/anify-auth/src/lib/types.ts +++ /dev/null @@ -1,269 +0,0 @@ -export const enum ProviderType { - ANIME = "ANIME", - MANGA = "MANGA", - META = "META", - INFORMATION = "INFORMATION", -} - -export const enum Type { - ANIME = "ANIME", - MANGA = "MANGA", -} - -export const enum Format { - TV = "TV", - TV_SHORT = "TV_SHORT", - MOVIE = "MOVIE", - SPECIAL = "SPECIAL", - OVA = "OVA", - ONA = "ONA", - MUSIC = "MUSIC", - MANGA = "MANGA", - NOVEL = "NOVEL", - ONE_SHOT = "ONE_SHOT", - UNKNOWN = "UNKNOWN", -} - -export const Formats = [Format.TV, Format.TV_SHORT, Format.MOVIE, Format.SPECIAL, Format.OVA, Format.ONA, Format.MUSIC, Format.MANGA, Format.NOVEL, Format.ONE_SHOT, Format.UNKNOWN]; - -export const enum Season { - WINTER = "WINTER", - SPRING = "SPRING", - SUMMER = "SUMMER", - FALL = "FALL", - UNKNOWN = "UNKNOWN", -} - -export const enum MediaStatus { - FINISHED = "FINISHED", - RELEASING = "RELEASING", - NOT_YET_RELEASED = "NOT_YET_RELEASED", - CANCELLED = "CANCELLED", - HIATUS = "HIATUS", -} - -export const enum Genres { - ACTION = "Action", - ADVENTURE = "Adventure", - ANIME_INFLUENCED = "Anime Influenced", - AVANT_GARDE = "Avant Garde", - AWARD_WINNING = "Award Winning", - BOYS_LOVE = "Boys Love", - CARS = "Cards", - COMEDY = "Comedy", - DEMENTIA = "Dementia", - DEMONS = "Demons", - DOUJINSHI = "Doujinshi", - DRAMA = "Drama", - ECCHI = "Ecchi", - EROTICA = "Erotica", - FAMILY = "Family", - FANTASY = "Fantasy", - FOOD = "Food", - FRIENDSHIP = "Friendship", - GAME = "Game", - GENDER_BENDER = "Gender Bender", - GIRLS_LOVE = "Girls Love", - GORE = "Gore", - GOURMET = "Gourmet", - HAREM = "Harem", - HENTAI = "Hentai", - HISTORICAL = "Historical", - HORROR = "Horror", - ISEKAI = "Isekai", - KIDS = "Kids", - MAGIC = "Magic", - MAHOU_SHOUJO = "Mahou Shoujo", - MARTIAL_ARTS = "Martial Arts", - MECHA = "Mecha", - MEDICAL = "Medical", - MILITARY = "Military", - MUSIC = "Music", - MYSTERY = "Mystery", - PARODY = "Parody", - POLICE = "Police", - POLITICAL = "Political", - PSYCHOLOGICAL = "Psychological", - RACING = "Racing", - ROMANCE = "Romance", - SAMURAI = "Samurai", - SCHOOL = "School", - SCI_FI = "Sci-Fi", - SHOUJO_AI = "Shoujo Ai", - SHOUNEN_AI = "Shounen Ai", - SLICE_OF_LIFE = "Slice of Life", - SPACE = "Space", - SPORTS = "Sports", - SUPER_POWER = "Super Power", - SUPERNATURAL = "Supernatural", - SUSPENCE = "Suspence", - THRILLER = "Thriller", - VAMPIRE = "Vampire", - WORKPLACE = "Workplace", - YAOI = "Yaoi", - YURI = "Yuri", - ZOMBIES = "Zombies", -} - -export type Anime = { - id: string; - slug: string; - coverImage: string | null; - bannerImage: string | null; - trailer: string | null; - status: MediaStatus | null; - season: Season; - title: { - romaji: string | null; - english: string | null; - native: string | null; - }; - currentEpisode: number | null; - mappings: { id: string; providerId: string; similarity: number; providerType: ProviderType | null }[]; - synonyms: string[]; - countryOfOrigin: string | null; - description: string | null; - duration: number | null; - color: string | null; - year: number | null; - rating: { - anilist: number; - mal: number; - kitsu: number; - }; - popularity: { - anilist: number; - mal: number; - kitsu: number; - }; - type: Type; - genres: Genres[]; - format: Format; - relations: Relations[]; - totalEpisodes?: number; - episodes: { - latest: { - updatedAt: number; - latestEpisode: number; - latestTitle: string; - }; - data: EpisodeData[]; - }; - tags: string[]; - artwork: Artwork[]; - characters: Character[]; -}; - -export type Manga = { - id: string; - slug: string; - coverImage: string | null; - bannerImage: string | null; - status: MediaStatus | null; - title: { - romaji: string | null; - english: string | null; - native: string | null; - }; - mappings: { id: string; providerId: string; similarity: number; providerType: ProviderType | null }[]; - synonyms: string[]; - countryOfOrigin: string | null; - description: string | null; - totalVolumes: number | null; - color: string | null; - year: number | null; - rating: { - anilist: number; - mal: number; - kitsu: number; - }; - popularity: { - anilist: number; - mal: number; - kitsu: number; - }; - genres: Genres[]; - type: Type; - format: Format; - relations: Relations[]; - totalChapters: number | null; - chapters: { - latest: { - updatedAt: number; - latestChapter: number; - latestTitle: string; - }; - data: ChapterData[]; - }; - tags: string[]; - artwork: Artwork[]; - characters: Character[]; -}; - -export interface Character { - name: string; - image: string; - voiceActor: { - name: string; - image: string; - }; -} - -export type Relations = { - id: string; - type: Type; - title: { - english: string | null; - romaji: string | null; - native: string | null; - }; - format: Format; - relationType: string; -}; - -export type Artwork = { - type: "banner" | "poster" | "clear_logo" | "top_banner" | "icon" | "clear_art"; - img: string; - providerId: string; -}; - -export type EpisodeData = { - providerId: string; - episodes: Episode[]; -}; - -export type ChapterData = { - providerId: string; - chapters: Chapter[]; -}; - -export type Episode = { - id: string; - title: string; - number: number; - isFiller: boolean; - img: string | null; - hasDub: boolean; - updatedAt?: number; -}; - -export type Chapter = { - id: string; - title: string; - number: number; - updatedAt?: number; - mixdrop?: string; -}; - -export type Settings = { - autoSkip: boolean; - autoFullscreen: boolean; - autoNext: boolean; - fontSize: string; - fontWidth: string; - titleLanguage: string; - displayAdultContent: boolean; - airingNotifications: boolean; - updatedAt?: Date; - createdAt?: Date; -}; diff --git a/anify-auth/src/providers/impl/anilist.ts b/anify-auth/src/providers/impl/anilist.ts index d653740..eecd81c 100644 --- a/anify-auth/src/providers/impl/anilist.ts +++ b/anify-auth/src/providers/impl/anilist.ts @@ -1,7 +1,6 @@ -import { FastifyReply, FastifyRequest } from "fastify"; import AuthProvider, { AdvancedScores, Entry, ListData } from "."; -import { env, providerEnv } from "@/src/env"; -import { generateUUID } from "@/src/helper"; +import { env, providerEnv } from "../../env"; +import { generateUUID } from "../../helper"; export default class AniList extends AuthProvider { override rateLimit = 250; @@ -333,8 +332,12 @@ export default class AniList extends AuthProvider { return data; } - override async handleAuth(req: FastifyRequest, res: FastifyReply): Promise { - const { code } = req.query as { code: string }; + override async handleAuth(req: Request, res: Response): Promise { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const code = url.searchParams.get("code"); try { const data: AniListResult = await ( @@ -354,9 +357,10 @@ export default class AniList extends AuthProvider { }) ).json(); - return res.redirect(`${env.FRONTEND_URL}/login?token=${encodeURIComponent(data.access_token)}&expires=${Date.now() + data.expires_in * 1000}&provider=${this.id}`); + // Redirect user + return Response.redirect(`${env.FRONTEND_URL}/login?token=${encodeURIComponent(data.access_token)}&expires=${Date.now() + data.expires_in * 1000}&provider=${this.id}`); } catch (e) { - return res.send({ error: e }); + return new Response(JSON.stringify({ error: (e as any).message }), { status: 500 }); } } diff --git a/anify-auth/src/providers/impl/index.ts b/anify-auth/src/providers/impl/index.ts index ab45980..e56a459 100644 --- a/anify-auth/src/providers/impl/index.ts +++ b/anify-auth/src/providers/impl/index.ts @@ -1,5 +1,4 @@ -import { isValidDate } from "@/src/helper"; -import { FastifyInstance, FastifyReply, FastifyRequest, RegisterOptions } from "fastify"; +import { isValidDate } from "../../helper"; export default abstract class AuthProvider { abstract rateLimit: number; @@ -15,8 +14,8 @@ export default abstract class AuthProvider { this.routes = this.routes.bind(this); } - async handleAuth(req: FastifyRequest, res: FastifyReply): Promise { - return; + async handleAuth(req: Request, res: Response): Promise { + return undefined; } async fetchList(userId: string, accessToken: string): Promise { @@ -49,105 +48,142 @@ export default abstract class AuthProvider { return entry; } - async routes(fastify: FastifyInstance, options: RegisterOptions): Promise { - fastify.get("/", (_, reply) => { - reply.status(200).send({ oauth: this.oauthURL }); - }); + routes(): { path: string; handler: any }[] { + const routes: { path: string; handler: any }[] = []; - fastify.get("/entry", async (request, reply) => { - const { userId, accessToken, mediaId } = request.query as { userId: string; accessToken: string; mediaId: string }; - - if (!userId || userId.length === 0) { - return reply.status(400).send({ error: "No user ID provided." }); - } - if (!accessToken || accessToken.length === 0) { - return reply.status(400).send({ error: "No access token provided." }); - } - if (!mediaId || mediaId.length === 0) { - return reply.status(400).send({ error: "No media ID provided." }); - } - - const list = await this.fetchEntry(userId, accessToken, mediaId); - return list; + routes.push({ + path: "/", + handler: () => { + return new Response(JSON.stringify({ oauth: this.oauthURL }), { headers: { "Content-Type": "application/json" } }); + }, }); - fastify.post("/entry", async (request, reply) => { - const { userId, accessToken, mediaId } = request.body as { userId: string; accessToken: string; mediaId: string }; - - if (!userId || userId.length === 0) { - return reply.status(400).send({ error: "No user ID provided." }); - } - if (!accessToken || accessToken.length === 0) { - return reply.status(400).send({ error: "No access token provided." }); - } - if (!mediaId || mediaId.length === 0) { - return reply.status(400).send({ error: "No media ID provided." }); - } + routes.push({ + path: "/entry", + handler: async (req: Request) => { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const userId = body?.userId || paths[0] || url.searchParams.get("userId"); + const accessToken = body?.accessToken || paths[1] || url.searchParams.get("accessToken"); + const mediaId = body?.mediaId || paths[2] || url.searchParams.get("mediaId"); + + if (!userId || userId.length === 0) { + return new Response(JSON.stringify({ error: "No user ID provided." }), { status: 400, headers: { "Content-Type": "application/json" } }); + } - const list = await this.fetchEntry(userId, accessToken, mediaId); - return list; - }); + if (!accessToken || accessToken.length === 0) { + return new Response(JSON.stringify({ error: "No access token provided." }), { status: 400, headers: { "Content-Type": "application/json" } }); + } - fastify.post("/update-entry", async (request, reply) => { - const { userId, accessToken, entry } = request.body as { userId: string; accessToken: string; entry: Entry }; + if (!mediaId || mediaId.length === 0) { + return new Response(JSON.stringify({ error: "No media ID provided." }), { status: 400, headers: { "Content-Type": "application/json" } }); + } - if (!userId || userId.length === 0) { - return reply.status(400).send({ error: "No user ID provided." }); - } - if (!accessToken || accessToken.length === 0) { - return reply.status(400).send({ error: "No access token provided." }); - } - if (!entry) { - return reply.status(400).send({ error: "No entry provided." }); - } + const list = await this.fetchEntry(userId, accessToken, mediaId); + return new Response(JSON.stringify(list), { headers: { "Content-Type": "application/json" } }); + }, + }); - const fieldsToChange: (keyof Entry)[] = ["startedAt", "completedAt", "updatedAt", "createdAt"]; + routes.push({ + path: "/update-entry", + handler: async (req: Request) => { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const userId = body?.userId || paths[0] || url.searchParams.get("userId"); + const accessToken = body?.accessToken || paths[1] || url.searchParams.get("accessToken"); + const entry = body?.entry || paths[2] || url.searchParams.get("entry"); + + if (!userId || userId.length === 0) { + return new Response(JSON.stringify({ error: "No user ID provided." }), { status: 400, headers: { "Content-Type": "application/json" } }); + } - for (const field of fieldsToChange) { - if (entry[field] !== undefined && entry[field] !== null && !isNaN(entry[field] as any)) { - (entry[field] as any) = new Date(entry[field] as any); + if (!accessToken || accessToken.length === 0) { + return new Response(JSON.stringify({ error: "No access token provided." }), { status: 400, headers: { "Content-Type": "application/json" } }); } - } - const list = await this.updateEntry(userId, accessToken, entry); - return list; - }); + if (!entry) { + return new Response(JSON.stringify({ error: "No entry provided." }), { status: 400, headers: { "Content-Type": "application/json" } }); + } - fastify.get("/list", async (request, reply) => { - const { userId, accessToken } = request.query as { userId: string; accessToken: string }; + const fieldsToChange: (keyof Entry)[] = ["startedAt", "completedAt", "updatedAt", "createdAt"]; - if (!userId || userId.length === 0) { - return reply.status(400).send({ error: "No user ID provided." }); - } - if (!accessToken || accessToken.length === 0) { - return reply.status(400).send({ error: "No access token provided." }); - } + for (const field of fieldsToChange) { + if (entry[field] !== undefined && entry[field] !== null && !isNaN(entry[field] as any)) { + (entry[field] as any) = new Date(entry[field] as any); + } + } - const list = await this.fetchList(userId, accessToken); - return list; + const list = await this.updateEntry(userId, accessToken, entry); + return new Response(JSON.stringify(list), { headers: { "Content-Type": "application/json" } }); + }, }); - fastify.post("/list", async (request, reply) => { - const { userId, accessToken } = request.body as { userId: string; accessToken: string }; + routes.push({ + path: "/list", + handler: async (req: Request) => { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const userId = body?.userId || paths[0] || url.searchParams.get("userId"); + const accessToken = body?.accessToken || paths[1] || url.searchParams.get("accessToken"); + + if (!userId || userId.length === 0) { + return new Response(JSON.stringify({ error: "No user ID provided." }), { status: 400, headers: { "Content-Type": "application/json" } }); + } - if (!userId || userId.length === 0) { - return reply.status(400).send({ error: "No user ID provided." }); - } - if (!accessToken || accessToken.length === 0) { - return reply.status(400).send({ error: "No access token provided." }); - } + if (!accessToken || accessToken.length === 0) { + return new Response(JSON.stringify({ error: "No access token provided." }), { status: 400, headers: { "Content-Type": "application/json" } }); + } - const list = await this.fetchList(userId, accessToken); - return list; + const list = await this.fetchList(userId, accessToken); + return new Response(JSON.stringify(list), { headers: { "Content-Type": "application/json" } }); + }, }); - fastify.get("/oauth", (_, reply) => { - reply.status(200).send({ oauth: this.oauthURL }); + routes.push({ + path: "/oauth", + handler: async (req: Request) => { + return new Response(JSON.stringify({ oauth: this.oauthURL }), { headers: { "Content-Type": "application/json" } }); + }, }); - fastify.get("/callback", async (request, reply) => { - return (await this.handleAuth(request, reply)) || reply.status(500).send({ error: "Something went wrong." }); + routes.push({ + path: "/callback", + handler: async (req: Request, res: Response) => { + const data = await this.handleAuth(req, res); + if (!data) return new Response(JSON.stringify({ error: "Something went wrong." }), { status: 500, headers: { "Content-Type": "application/json" } }); + + return new Response(JSON.stringify(data), { headers: { "Content-Type": "application/json" } }); + }, }); + + return routes; } abstract get oauthURL(): string; diff --git a/anify-auth/src/providers/impl/mal.ts b/anify-auth/src/providers/impl/mal.ts index ef2a72a..7ad0bf7 100644 --- a/anify-auth/src/providers/impl/mal.ts +++ b/anify-auth/src/providers/impl/mal.ts @@ -1,7 +1,5 @@ -import { env, providerEnv } from "@/src/env"; import AuthProvider, { Entry, ListData } from "."; -import { FastifyReply, FastifyRequest } from "fastify"; -import crypto from "crypto"; +import { env, providerEnv } from "../../env"; export default class MAL extends AuthProvider { override rateLimit = 250; @@ -134,7 +132,7 @@ export default class MAL extends AuthProvider { ).json(); } - function parseMediaType(mediaType) { + function parseMediaType(mediaType: string) { if (mediaType === "tv" || mediaType === "movie" || mediaType === "special" || mediaType === "ova" || mediaType === "ona" || mediaType === "music") { return "ANIME"; } else { @@ -210,8 +208,12 @@ export default class MAL extends AuthProvider { } } - override async handleAuth(req: FastifyRequest, res: FastifyReply): Promise { - const { code } = req.query as { code: string }; + override async handleAuth(req: Request, res: Response): Promise { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const code = url.searchParams.get("code"); try { const data: MALResponse = await ( @@ -224,25 +226,12 @@ export default class MAL extends AuthProvider { }) ).json(); - return res.redirect(`${env.FRONTEND_URL}/login?token=${encodeURIComponent(data.access_token)}&expires=${Date.now() + data.expires_in * 1000}&provider=${this.id}`); + return Response.redirect(`${env.FRONTEND_URL}/login?token=${encodeURIComponent(data.access_token)}&expires=${Date.now() + data.expires_in * 1000}&provider=${this.id}`); } catch (e) { - return res.send({ error: e }); + return new Response(JSON.stringify({ error: "Invalid code" }), { status: 400, headers: { "Content-Type": "application/json" } }); } } - private generateChallenge(verifier: string): string { - const bytes = Buffer.from(verifier, "ascii"); - const md = crypto.createHash("sha256"); - md.update(bytes); - const digest = md.digest(); - - // Convert the digest bytes to a URL-safe base64 string - const base64 = Buffer.from(digest).toString("base64"); - const urlSafeBase64 = base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); - - return urlSafeBase64; - } - get oauthURL(): string { return `${this.url}/v1/oauth2/authorize?response_type=code&client_id=${this.clientId}&redirect_uri=${this.redirectUri}&code_challenge=${this.codeVerifier}&code_challenge_method=plain`; } diff --git a/anify-auth/src/providers/index.ts b/anify-auth/src/providers/index.ts index 6b07498..2aab198 100644 --- a/anify-auth/src/providers/index.ts +++ b/anify-auth/src/providers/index.ts @@ -4,13 +4,16 @@ import MAL from "./impl/mal"; import Simkl from "./impl/simkl"; const AUTH_PROVIDERS: AuthProvider[] = [new AniList(), new MAL(), new Simkl()]; -const authProviders: Record = AUTH_PROVIDERS.reduce((acc, provider) => { - acc[provider.id] = provider; - return acc; -}, {}); +const authProviders: Record = AUTH_PROVIDERS.reduce( + (acc, provider) => { + acc[provider.id] = provider; + return acc; + }, + {} as Record, +); -const routes = AUTH_PROVIDERS.map((x) => { +const providerRoutes = AUTH_PROVIDERS.map((x) => { return { controller: x.routes, prefix: x.id }; }); -export { AUTH_PROVIDERS, authProviders, routes }; +export { AUTH_PROVIDERS, authProviders, providerRoutes }; diff --git a/anify-auth/src/scripts/buildDb.ts b/anify-auth/src/scripts/buildDb.ts deleted file mode 100644 index 543c764..0000000 --- a/anify-auth/src/scripts/buildDb.ts +++ /dev/null @@ -1,21 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import colors from "colors"; -import { execSync } from "child_process"; - -export const buildDb = async (): Promise => { - const scripts = ["npm run db:generate && npm run db:push && npm run db:validate"]; - - for (const script of scripts) { - try { - console.log(`Executing script: ${script}`); - execSync(script, { stdio: "inherit" }); - } catch (error) { - console.error(colors.red(`Error executing script: ${script}`)); - console.error(error); - } - } -}; - -buildDb(); diff --git a/anify-auth/src/scripts/checkEnv.ts b/anify-auth/src/scripts/checkEnv.ts deleted file mode 100644 index f3ffdf4..0000000 --- a/anify-auth/src/scripts/checkEnv.ts +++ /dev/null @@ -1,20 +0,0 @@ -import dotenv from "dotenv"; -dotenv.config(); - -import colors from "colors"; -import { env, providerEnv } from "../env"; - -const recommendedVariables = ["REDIS_URL", "REDIS_CACHE_TIME"].concat(Object.keys(providerEnv)); - -const requiredVariables = ["DATABASE_URL"]; -for (const variable of requiredVariables) { - if (!env[variable]) { - throw new Error(colors.red(`Missing environment variable ${variable}`)); - } -} - -for (const variable of recommendedVariables) { - if (!env[variable]) { - console.log(colors.yellow(`WARNING: Enviornment variable ${variable} not found.`)); - } -} diff --git a/anify-auth/src/scripts/clear.ts b/anify-auth/src/scripts/clear.ts deleted file mode 100644 index 9b9bf6a..0000000 --- a/anify-auth/src/scripts/clear.ts +++ /dev/null @@ -1,15 +0,0 @@ -import colors from "colors"; -import { unlink } from "fs/promises"; -import { join } from "path"; - -/** - * Clears the database - * @returns {Promise} - */ -export const clearDatabase = async (): Promise => { - await unlink(join(__dirname, "../../prisma/db.sqlite")); - - console.log(colors.red("Deleted database")); -}; - -clearDatabase().then(() => process.exit(0)); diff --git a/anify-auth/src/server/impl/createUser.ts b/anify-auth/src/server/impl/createUser.ts new file mode 100644 index 0000000..cdd4692 --- /dev/null +++ b/anify-auth/src/server/impl/createUser.ts @@ -0,0 +1,43 @@ +import { insertUser } from "../../database/impl/insert"; +import { hashPassword } from "../../helper"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const username = body?.username || paths[1] || url.searchParams.get("username"); + const password = body?.password || paths[2] || url.searchParams.get("password"); + const anilistId = body?.anilistId || paths[3] || url.searchParams.get("anilistId"); + const malId = body?.malId || paths[4] || url.searchParams.get("malId"); + const simklId = body?.simklId || paths[5] || url.searchParams.get("simklId"); + + const passData = await hashPassword(password); + + const data = await insertUser({ anilistId, malId, simklId }, username, passData.password, passData.salt); + if (!data) return new Response(JSON.stringify({ error: "User already exists." }), { status: 400, headers: { "Content-Type": "application/json" } }); + + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" } }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + path: "/create-user", + handler, +}; + +export default route; diff --git a/anify-auth/src/server/impl/login.ts b/anify-auth/src/server/impl/login.ts new file mode 100644 index 0000000..eaa0b38 --- /dev/null +++ b/anify-auth/src/server/impl/login.ts @@ -0,0 +1,37 @@ +import { login } from "../../database/impl/login"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const username = body?.username || paths[1] || url.searchParams.get("username"); + const password = body?.password || paths[2] || url.searchParams.get("password"); + + const data = await login(username, password); + if (!data) return new Response(JSON.stringify({ error: "Invalid username/password." }), { status: 400, headers: { "Content-Type": "application/json" } }); + + return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json" } }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + path: "/login", + handler, +}; + +export default route; diff --git a/anify-auth/src/server/impl/providers.ts b/anify-auth/src/server/impl/providers.ts new file mode 100644 index 0000000..8bae7f0 --- /dev/null +++ b/anify-auth/src/server/impl/providers.ts @@ -0,0 +1,55 @@ +import { cacheTime, redis } from ".."; +import { AUTH_PROVIDERS } from "../../providers"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const cached = await redis.get(`auth-providers`); + if (cached) { + return new Response(JSON.stringify(cached), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + + const data = AUTH_PROVIDERS.map((x) => { + return { + id: x.id, + url: x.url, + name: x.name, + icon: x.icon, + oauth: x.oauthURL, + }; + }); + + if (!data) { + return new Response(JSON.stringify({ error: "No data found." }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + } + + await redis.set(`auth-providers`, JSON.stringify(data), "EX", cacheTime); + + return new Response(JSON.stringify(data), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + path: "/providers", + handler, +}; + +export default route; diff --git a/anify-auth/src/server/impl/updateUser.ts b/anify-auth/src/server/impl/updateUser.ts new file mode 100644 index 0000000..54bbfd3 --- /dev/null +++ b/anify-auth/src/server/impl/updateUser.ts @@ -0,0 +1,41 @@ +import { get } from "../../database/impl/get"; +import { updateUser } from "../../database/impl/update"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const id = body?.id || paths[1] || url.searchParams.get("id"); + const anilistId = body?.anilistId || paths[2] || url.searchParams.get("anilistId"); + const malId = body?.malId || paths[3] || url.searchParams.get("malId"); + const simklId = body?.simklId || paths[4] || url.searchParams.get("simklId"); + + if (!id) return new Response(JSON.stringify({ error: "No user ID provided." }), { status: 400, headers: { "Content-Type": "application/json" } }); + + await updateUser(id, { anilistId, malId, simklId }); + + return new Response(JSON.stringify(await get(id)), { status: 200, headers: { "Content-Type": "application/json" } }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + path: "/update-user", + handler, +}; + +export default route; diff --git a/anify-auth/src/server/impl/user.ts b/anify-auth/src/server/impl/user.ts new file mode 100644 index 0000000..59f80fb --- /dev/null +++ b/anify-auth/src/server/impl/user.ts @@ -0,0 +1,45 @@ +import { get } from "../../database/impl/get"; + +export const handler = async (req: Request): Promise => { + try { + const url = new URL(req.url); + const paths = url.pathname.split("/"); + paths.shift(); + + const body = + req.method === "POST" + ? await req.json().catch(() => { + return null; + }) + : null; + + const userId = body?.id || paths[0] || url.searchParams.get("id"); + + const data = await get(userId); + + if (!data) { + return new Response(JSON.stringify({ error: "No data found." }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + } + + return new Response(JSON.stringify(data), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (e) { + console.error(e); + return new Response(JSON.stringify({ error: "An error occurred." }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +const route = { + path: "/user", + handler, +}; + +export default route; diff --git a/anify-auth/src/server/index.ts b/anify-auth/src/server/index.ts new file mode 100644 index 0000000..2489565 --- /dev/null +++ b/anify-auth/src/server/index.ts @@ -0,0 +1,68 @@ +import { readdirSync } from "node:fs"; +import { join } from "node:path"; + +import Redis from "ioredis"; + +import colors from "colors"; + +import { env } from "../env"; +import { providerRoutes } from "../providers"; + +export const redis: Redis = env.REDIS_URL + ? new Redis((env.REDIS_URL as string) || "redis://localhost:6379") + : ({ + get: async () => null, + set: (): Promise<"OK"> => Promise.resolve("OK"), + on: () => Redis.prototype, + keys: async () => [], + connect: async () => void 0, + call: async () => void 0, + } as any); + +export const cacheTime = env.REDIS_CACHE_TIME || 60 * 60 * 24 * 7 * 2; + +export const start = async () => { + const routes: { [key: string]: { path: string; handler: (req: Request) => Promise } } = {}; + const routeFiles = readdirSync(join(import.meta.dir, "./impl")); + for (const file of routeFiles) { + const routeModule = await import(join(import.meta.dir, "./impl", file)); + const route = routeModule.default; + + if (route) { + const { path, handler } = route; + routes[path] = { path, handler }; + } + } + + Bun.serve({ + port: env.PORT, + async fetch(req: Request) { + const url = new URL(req.url); + if (url.pathname === "/") return new Response("Welcome to Anify authentication! 🎉 Documentation can be viewed at https://docs.anify.tv. Join our Discord https://anify.tv/discord for more information.", { headers: { "Content-Type": "application/json" } }); + + const pathName = `/${url.pathname.split("/").slice(1)[0]}`; + const fullRoute = `/${url.pathname.split("/").slice(1).join("/")}`; + + for (const route of providerRoutes) { + if (`/${route.prefix}` === pathName) { + const routes = route.controller(); + for (const suffix of routes) { + if (`/${route.prefix}${suffix.path}` === fullRoute) { + console.log("WOWOOWOW"); + return suffix.handler(req); + } + } + } + } + + if (routes[pathName]) { + const { path, handler } = routes[pathName]; + return handler(req); + } + + return new Response(JSON.stringify({ error: "Route not found" }), { status: 404, headers: { "Content-Type": "application/json" } }); + }, + }); + + console.log(colors.blue(`Server is now listening on ${env.PORT}`)); +}; diff --git a/anify-auth/src/types/index.ts b/anify-auth/src/types/index.ts new file mode 100644 index 0000000..cc60249 --- /dev/null +++ b/anify-auth/src/types/index.ts @@ -0,0 +1,5 @@ +export interface IDs { + anilistId?: string; + malId?: string; + simklId?: string; +} diff --git a/anify-auth/tsconfig.json b/anify-auth/tsconfig.json index f3b9dff..1449bc3 100644 --- a/anify-auth/tsconfig.json +++ b/anify-auth/tsconfig.json @@ -1,33 +1,22 @@ { - "compilerOptions": { - "target": "esnext", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "esModuleInterop": true, - "module": "CommonJS", - "moduleResolution": "node", - "resolveJsonModule": true, - "noImplicitAny": false, - "isolatedModules": false, - "allowSyntheticDefaultImports": true, - "jsx": "preserve", - "incremental": true, - "declaration": true, - "baseUrl": ".", - "paths": { - "@/*": ["./*"], - "database": ["./src/database"] - }, - "outDir": "./dist" - }, - "include": ["src"], - "exclude": ["node_modules", "dist"], - "ts-node": { - "compilerOptions": { - "module": "commonjs" - } - } + "compilerOptions": { + "lib": ["ESNext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "jsx": "preserve", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [ + "bun-types" // add Bun global + ] + } } diff --git a/anify-auth/yarn.lock b/anify-auth/yarn.lock deleted file mode 100644 index b942e58..0000000 --- a/anify-auth/yarn.lock +++ /dev/null @@ -1,3864 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - -"@cspotcode/source-map-support@^0.8.0": - 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== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - -"@eslint/eslintrc@^2.1.0": - version "2.1.0" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz" - integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.44.0": - version "8.44.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz" - integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== - -"@fastify/ajv-compiler@^3.5.0": - version "3.5.0" - resolved "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.5.0.tgz" - integrity sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA== - dependencies: - ajv "^8.11.0" - ajv-formats "^2.1.1" - fast-uri "^2.0.0" - -"@fastify/cors@^8.3.0": - version "8.3.0" - resolved "https://registry.npmjs.org/@fastify/cors/-/cors-8.3.0.tgz" - integrity sha512-oj9xkka2Tg0MrwuKhsSUumcAkfp2YCnKxmFEusi01pjk1YrdDsuSYTHXEelWNW+ilSy/ApZq0c2SvhKrLX0H1g== - dependencies: - fastify-plugin "^4.0.0" - mnemonist "0.39.5" - -"@fastify/deepmerge@^1.0.0": - version "1.3.0" - resolved "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-1.3.0.tgz" - integrity sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A== - -"@fastify/error@^3.2.0": - version "3.3.0" - resolved "https://registry.npmjs.org/@fastify/error/-/error-3.3.0.tgz" - integrity sha512-dj7vjIn1Ar8sVXj2yAXiMNCJDmS9MQ9XMlIecX2dIzzhjSHCyKo4DdXjXMs7wKW2kj6yvVRSpuQjOZ3YLrh56w== - -"@fastify/fast-json-stringify-compiler@^4.3.0": - version "4.3.0" - resolved "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz" - integrity sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA== - dependencies: - fast-json-stringify "^5.7.0" - -"@humanwhocodes/config-array@^0.11.10": - version "0.11.10" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz" - integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@ioredis/commands@^1.1.1": - version "1.2.0" - resolved "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz" - integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@jridgewell/resolve-uri@^3.0.3": - 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== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@mapbox/node-pre-gyp@^1.0.11": - version "1.0.11" - resolved "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz" - integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== - dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@prisma/client@^4.15.0": - version "4.15.0" - resolved "https://registry.npmjs.org/@prisma/client/-/client-4.15.0.tgz" - integrity sha512-xnROvyABcGiwqRNdrObHVZkD9EjkJYHOmVdlKy1yGgI+XOzvMzJ4tRg3dz1pUlsyhKxXGCnjIQjWW+2ur+YXuw== - dependencies: - "@prisma/engines-version" "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944" - -"@prisma/debug@4.13.0": - version "4.13.0" - resolved "https://registry.npmjs.org/@prisma/debug/-/debug-4.13.0.tgz" - integrity sha512-JrltTewF/paRb5mcM5OvcEi9DtdX0sINOAswruxKQrwOLA7Phqb52OfY38MIzGrsrJ8iUGVqQ5bpYZYpxOGCsQ== - dependencies: - "@types/debug" "4.1.7" - debug "4.3.4" - strip-ansi "6.0.1" - -"@prisma/engines-version@4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944": - version "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944" - resolved "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944.tgz" - integrity sha512-sVOig4tjGxxlYaFcXgE71f/rtFhzyYrfyfNFUsxCIEJyVKU9rdOWIlIwQ2NQ7PntvGnn+x0XuFo4OC1jvPJKzg== - -"@prisma/engines@5.0.0": - version "5.0.0" - resolved "https://registry.npmjs.org/@prisma/engines/-/engines-5.0.0.tgz" - integrity sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg== - -"@prisma/generator-helper@^4.10.1": - version "4.13.0" - resolved "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-4.13.0.tgz" - integrity sha512-Zx9rtbsEIU/9DKnGRvmjLdyeyhzeeXNFp1alkRh1w//rQ5jTcobiay/jU4Qo+EQOs2bnWEfUeiBoOjfaysdLNg== - dependencies: - "@prisma/debug" "4.13.0" - "@types/cross-spawn" "6.0.2" - chalk "4.1.2" - cross-spawn "7.0.3" - -"@swc/helpers@^0.3.13": - version "0.3.17" - resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.3.17.tgz" - integrity sha512-tb7Iu+oZ+zWJZ3HJqwx8oNwSDIU440hmVMDPhpACWQWnrZHK99Bxs70gT1L2dnr5Hg50ZRWEFkQCAnOVVV0z1Q== - dependencies: - tslib "^2.4.0" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== - -"@types/cross-spawn@6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz" - integrity sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw== - dependencies: - "@types/node" "*" - -"@types/debug@4.1.7": - version "4.1.7" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== - dependencies: - "@types/ms" "*" - -"@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/minimatch@*": - version "5.1.2" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - -"@types/ms@*": - version "0.7.31" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/node@*", "@types/node@^18.16.16": - version "18.16.16" - resolved "https://registry.npmjs.org/@types/node/-/node-18.16.16.tgz" - integrity sha512-NpaM49IGQQAUlBhHMF82QH80J08os4ZmyF9MkpCzWAGuOHqE4gTEbhzd7L3l5LmWuZ6E0OiC1FweQ4tsiW35+g== - -"@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@typescript-eslint/eslint-plugin@^5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz" - integrity sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/type-utils" "5.59.8" - "@typescript-eslint/utils" "5.59.8" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz" - integrity sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw== - dependencies: - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/typescript-estree" "5.59.8" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz" - integrity sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig== - dependencies: - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/visitor-keys" "5.59.8" - -"@typescript-eslint/type-utils@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz" - integrity sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA== - dependencies: - "@typescript-eslint/typescript-estree" "5.59.8" - "@typescript-eslint/utils" "5.59.8" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz" - integrity sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w== - -"@typescript-eslint/typescript-estree@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz" - integrity sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg== - dependencies: - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/visitor-keys" "5.59.8" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz" - integrity sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/typescript-estree" "5.59.8" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.8": - version "5.59.8" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz" - integrity sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ== - dependencies: - "@typescript-eslint/types" "5.59.8" - eslint-visitor-keys "^3.3.0" - -abbrev@1: - version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -abstract-logging@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz" - integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== - -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.4.1, acorn@^8.9.0: - version "8.9.0" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz" - integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== - -agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.0: - version "8.12.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ajv@^8.10.0: - version "8.12.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ajv@^8.11.0: - version "8.12.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz" - integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== - -are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" - integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" - integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== - -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" - integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== - dependencies: - array-uniq "^1.0.1" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" - integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" - integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -atomic-sleep@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz" - integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -avvio@^8.2.1: - version "8.2.1" - resolved "https://registry.npmjs.org/avvio/-/avvio-8.2.1.tgz" - integrity sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw== - dependencies: - archy "^1.0.0" - debug "^4.0.0" - fastq "^1.6.1" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -base64-js@^1.1.2, base64-js@^1.3.0, base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -base64-js@0.0.8: - version "0.0.8" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz" - integrity sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw== - -bcrypt@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz" - integrity sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.11" - node-addon-api "^5.0.0" - -body-parser@^1.20.2: - version "1.20.2" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== - dependencies: - bytes "3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.2" - type-is "~1.6.18" - unpipe "1.0.0" - -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brotli@^1.3.2: - version "1.3.3" - resolved "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz" - integrity sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg== - dependencies: - base64-js "^1.1.2" - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -call-me-maybe@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz" - integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -chalk@^4.0.0, chalk@4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -cheerio-select@^2.1.0: - version "2.1.0" - 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" - css-what "^6.1.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - -cheerio@1.0.0-rc.12: - version "1.0.0-rc.12" - 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" - domhandler "^5.0.3" - domutils "^3.0.1" - htmlparser2 "^8.0.1" - parse5 "^7.0.0" - parse5-htmlparser2-tree-adapter "^7.0.0" - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz" - integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== - -cluster-key-slot@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz" - integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" - integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-support@^1.1.2: - version "1.1.3" - resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -colors@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -console-control-strings@^1.0.0, console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4, content-type@~1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -cookie-parser@^1.4.6: - version "1.4.6" - resolved "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz" - integrity sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA== - dependencies: - cookie "0.4.1" - cookie-signature "1.0.6" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@^0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - -cookie@0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== - -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" - integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== - -copyfiles@^2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz" - integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg== - dependencies: - glob "^7.0.5" - minimatch "^3.0.3" - mkdirp "^1.0.4" - noms "0.0.0" - through2 "^2.0.1" - untildify "^4.0.0" - yargs "^16.1.0" - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - -cors@^2.8.5: - version "2.8.5" - resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-js@^4.0.0, crypto-js@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz" - integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== - -css-select@^5.1.0: - version "5.1.0" - 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" - domhandler "^5.0.2" - domutils "^3.0.1" - nth-check "^2.0.1" - -css-what@^6.1.0: - version "6.1.0" - resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - -debug@^2.2.0: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^2.3.3: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^4.0.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@4, debug@4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -decode-uri-component@^0.2.0: - version "0.2.2" - resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" - integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== - -deep-equal@^2.0.5: - version "2.2.2" - resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz" - integrity sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - es-get-iterator "^1.1.3" - get-intrinsic "^1.2.1" - is-arguments "^1.1.1" - is-array-buffer "^3.0.2" - is-date-object "^1.0.5" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - isarray "^2.0.5" - object-is "^1.1.5" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.0" - side-channel "^1.0.4" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" - -deep-is@^0.1.3: - 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== - -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" - integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" - integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -denque@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz" - integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detect-libc@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== - -dfa@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz" - integrity sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz" - integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== - dependencies: - path-type "^3.0.0" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-serializer@^2.0.0: - version "2.0.0" - 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" - entities "^4.2.0" - -domelementtype@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: - version "5.0.3" - resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" - integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== - dependencies: - domelementtype "^2.3.0" - -domutils@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz" - integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== - dependencies: - dom-serializer "^2.0.0" - domelementtype "^2.3.0" - domhandler "^5.0.1" - -dotenv@^16.1.4: - version "16.1.4" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz" - integrity sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw== - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -entities@^4.2.0, entities@^4.4.0: - version "4.5.0" - resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" - integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== - -es-get-iterator@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz" - integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - has-symbols "^1.0.3" - is-arguments "^1.1.1" - is-map "^2.0.2" - is-set "^2.0.2" - is-string "^1.0.7" - isarray "^2.0.5" - stop-iteration-iterator "^1.0.0" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint@*, "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", eslint@^8.45.0: - version "8.45.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz" - integrity sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.1.0" - "@eslint/js" "8.44.0" - "@humanwhocodes/config-array" "^0.11.10" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.6.0" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -espree@^9.6.0: - version "9.6.0" - resolved "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz" - integrity sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -events@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" - integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -express-rate-limit@^6: - version "6.7.0" - resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.7.0.tgz" - integrity sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA== - -"express@^4 || ^5": - version "4.18.2" - resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.1" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.11.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -fast-content-type-parse@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.0.0.tgz" - integrity sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA== - -fast-decode-uri-component@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz" - integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - 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== - -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - 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" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-json-stringify@^5.7.0: - version "5.8.0" - resolved "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.8.0.tgz" - integrity sha512-VVwK8CFMSALIvt14U8AvrSzQAwN/0vaVRiFFUVlpnXSnDGrSkOAO5MtzyN8oQNjLd5AqTW5OZRgyjoNuAuR3jQ== - dependencies: - "@fastify/deepmerge" "^1.0.0" - ajv "^8.10.0" - ajv-formats "^2.1.1" - fast-deep-equal "^3.1.3" - fast-uri "^2.1.0" - rfdc "^1.2.0" - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fast-querystring@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz" - integrity sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg== - dependencies: - fast-decode-uri-component "^1.0.1" - -fast-redact@^3.1.1: - version "3.3.0" - resolved "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz" - integrity sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ== - -fast-uri@^2.0.0, fast-uri@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-2.2.0.tgz" - integrity sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg== - -fastify-plugin@^4.0.0: - version "4.5.1" - resolved "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz" - integrity sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ== - -fastify@^4.21.0: - version "4.21.0" - resolved "https://registry.npmjs.org/fastify/-/fastify-4.21.0.tgz" - integrity sha512-tsu4bcwE4HetxqW8prA5fbC9bKHMYDp7jGEDWyzK1l90a3uOaLoIcQbdGcWeODNLVJviQnzh1wvIjTZE3MJFEg== - dependencies: - "@fastify/ajv-compiler" "^3.5.0" - "@fastify/error" "^3.2.0" - "@fastify/fast-json-stringify-compiler" "^4.3.0" - abstract-logging "^2.0.1" - avvio "^8.2.1" - fast-content-type-parse "^1.0.0" - fast-json-stringify "^5.7.0" - find-my-way "^7.6.0" - light-my-request "^5.9.1" - pino "^8.12.0" - process-warning "^2.2.0" - proxy-addr "^2.0.7" - rfdc "^1.3.0" - secure-json-parse "^2.5.0" - semver "^7.5.0" - tiny-lru "^11.0.1" - -fastq@^1.6.0, fastq@^1.6.1: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" - integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - -find-my-way@^7.6.0: - version "7.6.2" - resolved "https://registry.npmjs.org/find-my-way/-/find-my-way-7.6.2.tgz" - integrity sha512-0OjHn1b1nCX3eVbm9ByeEHiscPYiHLfhei1wOUU9qffQkk98wE0Lo8VrVYfSGMgnSnDh86DxedduAnBf4nwUEw== - dependencies: - fast-deep-equal "^3.1.3" - fast-querystring "^1.0.0" - safe-regex2 "^2.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -fontkit@^1.8.1: - version "1.9.0" - resolved "https://registry.npmjs.org/fontkit/-/fontkit-1.9.0.tgz" - integrity sha512-HkW/8Lrk8jl18kzQHvAw9aTHe1cqsyx5sDnxncx652+CIfhawokEPkeM3BoIC+z/Xv7a0yMr0f3pRRwhGH455g== - dependencies: - "@swc/helpers" "^0.3.13" - brotli "^1.3.2" - clone "^2.1.2" - deep-equal "^2.0.5" - dfa "^1.2.0" - restructure "^2.0.1" - tiny-inflate "^1.0.3" - unicode-properties "^1.3.1" - unicode-trie "^2.0.0" - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" - integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== - -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" - integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" - integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz" - integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz" - integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== - -glob@^10.2.5: - version "10.2.6" - resolved "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz" - integrity sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.0.3" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2" - path-scurry "^1.7.0" - -glob@^7.0.5, glob@^7.1.3: - version "7.1.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - 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" - -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - 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" - -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -has-bigints@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-proto@^1.0.1: - 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== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" - integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" - integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" - integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" - integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -htmlparser2@^8.0.1: - version "8.0.2" - resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz" - integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - entities "^4.4.0" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.3: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - 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" - -inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3, inherits@2, inherits@2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -internal-slot@^1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== - dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" - side-channel "^1.0.4" - -ioredis@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz" - integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== - dependencies: - "@ioredis/commands" "^1.1.1" - cluster-key-slot "^1.1.0" - debug "^4.3.4" - denque "^2.1.0" - lodash.defaults "^4.2.0" - lodash.isarguments "^3.1.0" - redis-errors "^1.2.0" - redis-parser "^3.0.0" - standard-as-callback "^2.1.0" - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" - integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arguments@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-callable@^1.1.3: - version "1.2.7" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - 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== - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz" - integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-map@^2.0.1, is-map@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" - integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== - dependencies: - kind-of "^3.0.2" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - 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== - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-set@^2.0.1, is-set@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== - -is-shared-array-buffer@^1.0.2: - 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== - dependencies: - call-bind "^1.0.2" - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10: - version "1.1.12" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - -is-weakset@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" - integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isarray@~1.0.0, isarray@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" - integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -jackspeak@^2.0.3: - version "2.2.1" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz" - integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^2.2.2: - version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" - integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0: - version "6.0.3" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -light-my-request@^5.9.1: - version "5.10.0" - resolved "https://registry.npmjs.org/light-my-request/-/light-my-request-5.10.0.tgz" - integrity sha512-ZU2D9GmAcOUculTTdH9/zryej6n8TzT+fNGdNtm6SDp5MMMpHrJJkvAdE3c6d8d2chE9i+a//dS9CWZtisknqA== - dependencies: - cookie "^0.5.0" - process-warning "^2.0.0" - set-cookie-parser "^2.4.1" - -linebreak@^1.0.2: - version "1.1.0" - resolved "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz" - integrity sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ== - dependencies: - base64-js "0.0.8" - unicode-trie "^2.0.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz" - integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== - -lodash.isarguments@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz" - integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lru-cache@^6.0.0: - 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" - -lru-cache@^9.1.1: - version "9.1.2" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz" - integrity sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ== - -make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" - integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== - dependencies: - object-visit "^1.0.0" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromatch@^3.1.10: - version "3.1.10" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - 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" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: - 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" - -minimatch@^9.0.1: - version "9.0.1" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz" - integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -minipass@^3.0.0: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -"minipass@^5.0.0 || ^6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== - -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mnemonist@0.39.5: - version "0.39.5" - resolved "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.5.tgz" - integrity sha512-FPUtkhtJ0efmEFGpU14x7jGbTB+s18LrzRL2KgoWz9YvcY3cPomz8tih01GbHwnGk/OmkOKfqd/RAQoc8Lm7DQ== - dependencies: - obliterator "^2.0.1" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -node-addon-api@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz" - integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== - -node-fetch@^2.6.7: - version "2.6.13" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz" - integrity sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA== - dependencies: - whatwg-url "^5.0.0" - -noms@0.0.0: - version "0.0.0" - resolved "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz" - integrity sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow== - dependencies: - inherits "^2.0.1" - readable-stream "~1.0.31" - -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - -npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - -nth-check@^2.0.1: - version "2.1.1" - 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" - -object-assign@^4, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" - integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== - -object-is@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" - integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" - integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== - dependencies: - isobject "^3.0.1" - -obliterator@^2.0.1: - version "2.0.4" - resolved "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz" - integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== - -on-exit-leak-free@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz" - integrity sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w== - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -once@^1.3.0: - 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" - -optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - 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== - dependencies: - p-limit "^3.0.2" - -pako@^0.2.5: - version "0.2.9" - resolved "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz" - integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA== - -parent-module@^1.0.0: - 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== - dependencies: - callsites "^3.0.0" - -parse5-htmlparser2-tree-adapter@^7.0.0: - version "7.0.0" - 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" - -parse5@^7.0.0: - version "7.1.2" - resolved "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz" - integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== - dependencies: - entities "^4.4.0" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" - integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz" - integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-scurry@^1.7.0: - version "1.9.2" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz" - integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg== - dependencies: - lru-cache "^9.1.1" - minipass "^5.0.0 || ^6.0.2" - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pdfkit@^0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/pdfkit/-/pdfkit-0.13.0.tgz" - integrity sha512-AW79eHU5eLd2vgRDS9z3bSoi0FA+gYm+100LLosrQQMLUzOBGVOhG7ABcMFpJu7Bpg+MT74XYHi4k9EuU/9EZw== - dependencies: - crypto-js "^4.0.0" - fontkit "^1.8.1" - linebreak "^1.0.2" - png-js "^1.0.0" - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pino-abstract-transport@v1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz" - integrity sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA== - dependencies: - readable-stream "^4.0.0" - split2 "^4.0.0" - -pino-std-serializers@^6.0.0: - version "6.2.2" - resolved "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz" - integrity sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA== - -pino@^8.12.0: - version "8.15.0" - resolved "https://registry.npmjs.org/pino/-/pino-8.15.0.tgz" - integrity sha512-olUADJByk4twxccmAxb1RiGKOSvddHugCV3wkqjyv+3Sooa2KLrmXrKEWOKi0XPCLasRR5jBXxioE1jxUa4KzQ== - dependencies: - atomic-sleep "^1.0.0" - fast-redact "^3.1.1" - on-exit-leak-free "^2.1.0" - pino-abstract-transport v1.0.0 - pino-std-serializers "^6.0.0" - process-warning "^2.0.0" - quick-format-unescaped "^4.0.3" - real-require "^0.2.0" - safe-stable-stringify "^2.3.1" - sonic-boom "^3.1.0" - thread-stream "^2.0.0" - -png-js@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz" - integrity sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g== - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" - integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier@2.8.8: - version "2.8.8" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -prisma-json-types-generator@^2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-2.4.0.tgz" - integrity sha512-iOdo8sBoUz2jCi+kw5nwACbe0QHcPIIEToXyvn0cW5IJhPEhoYbY/XwMhEDIEla247YhXe1yYPiKwviFm9LNpg== - dependencies: - "@prisma/generator-helper" "^4.10.1" - tslib "^2.5.0" - -prisma@*, prisma@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/prisma/-/prisma-5.0.0.tgz" - integrity sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA== - dependencies: - "@prisma/engines" "5.0.0" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process-warning@^2.0.0, process-warning@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz" - integrity sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" - integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== - -proxy-addr@^2.0.7, proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -qs@6.11.0: - version "6.11.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -quick-format-unescaped@^4.0.3: - version "4.0.4" - resolved "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz" - integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -rate-limit-redis@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-3.0.2.tgz" - integrity sha512-4SBK6AzIr9PKkCF4HmSDcJH2O2KKMF3fZEcsbNMXyaL5I9d6X71uOreUldFRiyrRyP+qkQrTxzJ38ZKKN+sScw== - -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^4.0.0: - version "4.4.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz" - integrity sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA== - dependencies: - abort-controller "^3.0.0" - buffer "^6.0.3" - events "^3.3.0" - process "^0.11.10" - string_decoder "^1.3.0" - -readable-stream@~1.0.31: - version "1.0.34" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" - integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@~2.3.6: - version "2.3.8" - 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" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -real-require@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz" - integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== - -redis-errors@^1.0.0, redis-errors@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz" - integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== - -redis-parser@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz" - integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== - dependencies: - redis-errors "^1.0.0" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz" - integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - functions-have-names "^1.2.3" - -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - -require-directory@^2.1.1: - 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== - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" - integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== - -restructure@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/restructure/-/restructure-2.0.1.tgz" - integrity sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg== - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -ret@~0.2.0: - version "0.2.2" - resolved "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz" - integrity sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rfdc@^1.2.0, rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rimraf@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz" - integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== - dependencies: - glob "^10.2.5" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@~5.2.0, safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" - integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== - dependencies: - ret "~0.1.10" - -safe-regex2@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz" - integrity sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ== - dependencies: - ret "~0.2.0" - -safe-stable-stringify@^2.3.1: - version "2.4.3" - resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz" - integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -secure-json-parse@^2.5.0: - version "2.7.0" - resolved "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz" - integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== - -semver@^6.0.0: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.3.5, semver@^7.3.7, semver@^7.5.0: - version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -send@0.18.0: - version "0.18.0" - resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - -set-cookie-parser@^2.4.1: - version "2.6.0" - resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz" - integrity sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ== - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.0: - version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz" - integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -sonic-boom@^3.1.0: - version "3.3.0" - resolved "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz" - integrity sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g== - dependencies: - atomic-sleep "^1.0.0" - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -split2@^4.0.0: - version "4.2.0" - resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz" - integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== - -standard-as-callback@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz" - integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" - integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -stop-iteration-iterator@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" - integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== - dependencies: - internal-slot "^1.0.4" - -string_decoder@^1.1.1: - 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== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@^1.3.0: - 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== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - -string_decoder@~1.1.1: - version "1.1.1" - 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" - -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1, strip-ansi@6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-json-comments@^3.1.1: - 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== - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -tar@^6.1.11: - version "6.1.15" - resolved "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz" - integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thread-stream@^2.0.0: - version "2.4.0" - resolved "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.0.tgz" - integrity sha512-xZYtOtmnA63zj04Q+F9bdEay5r47bvpo1CaNqsKi7TpoJHcotUez8Fkfo2RJWpW91lnnaApdpRbVwCWsy+ifcw== - dependencies: - real-require "^0.2.0" - -through2@^2.0.1: - version "2.0.5" - resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -tiny-inflate@^1.0.0, tiny-inflate@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz" - integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== - -tiny-lru@^11.0.1: - version "11.0.1" - resolved "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.0.1.tgz" - integrity sha512-iNgFugVuQgBKrqeO/mpiTTgmBsTP0WL6yeuLfLs/Ctf0pI/ixGqIRm8sDCwMcXGe9WWvt2sGXI5mNqZbValmJg== - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" - integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" - integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex-range@^5.0.1: - 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== - dependencies: - is-number "^7.0.0" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -ts-node@^10.9.1: - version "10.9.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - 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" - -tsconfig-paths@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tscpaths@^0.0.9: - version "0.0.9" - resolved "https://registry.npmjs.org/tscpaths/-/tscpaths-0.0.9.tgz" - integrity sha512-tz4qimSJTCjYtHVsoY7pvxLcxhmhgmwzm7fyMEiL3/kPFFVyUuZOwuwcWwjkAsIrSUKJK22A7fNuJUwxzQ+H+w== - dependencies: - commander "^2.20.0" - globby "^9.2.0" - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.4.0, tslib@^2.5.0, tslib@^2.5.3: - version "2.5.3" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz" - integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.20.2: - 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== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typescript@^4.9.5, typescript@>=2.7, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": - version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -unicode-properties@^1.3.1: - version "1.4.1" - resolved "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz" - integrity sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg== - dependencies: - base64-js "^1.3.0" - unicode-trie "^2.0.0" - -unicode-trie@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz" - integrity sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ== - dependencies: - pako "^0.2.5" - tiny-inflate "^1.0.0" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unpipe@~1.0.0, unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" - integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" - integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -v8-compile-cache-lib@^3.0.1: - 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== - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - 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" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - -which-typed-array@^1.1.11, which-typed-array@^1.1.9: - version "1.1.11" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz" - integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.2: - version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs@^16.1.0: - version "16.2.0" - resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/anify-backend/db.sqlite b/anify-backend/db.sqlite index 33e12d7f24b7bfe1fd90292dc9c9ce37d1e76770..9661d2b6be594912253a56fb7a15e12a16fb1572 100644 GIT binary patch delta 1761 zcma*nT})GF7zgn4o{ydu5ZWWQAR=vD!4I@O{i0=lP#FjUf}7$Db6Fz{t5`k??89tv zl1PRbVwiipFbV7cMinWG>EStBG#eAa4IwYU0+5HTm`A z&@A zaUN?BxuXd-o#4e5O`Ks5^M?5r0Ys2Mr|~VaWG$TII3Wk}kVxP<4@St=tUdAt!Oktg zcJg5{C}08%;1J+)VbSpYm<)O_Ko(>}4kVxDLLL~w1PUyMd{_czus{J6!cr)LWl#*u zp#-d813RpMr@#TFPzEbu6|9CeP!4Nh9XP=SD!9P|Uhsh*Dj)zssD!6sJ#2uD+Wpw3 z+!uI`qg!Vr3vFl)ZKN~z`H$(F=8ziS^YsTJJ%7EmfO?K8ljCETMf&tQtD=Ov^`q3? zJFoE7)O}3Rk@JXhIzD#!eVOfz_QYzK+xyU5DLT|&$OSa@>tKXNN zt&^;`O%|G)UuK}yO-!L_8#7YRq*Cfo-Kxvy&KMs^$M?~tdpphaRTC?wvjxc=x+~OF z5Fm*_(3 zz(Ha~iX~^DFB*w;|ZWiboE8SOk=*C%eB`7?5IpLHddysv9i-Fc_szge%rg8ezY+&KR-p` zJ3^cGi-G0q=!#IXK3Djw-y2x;9h)#2^W>=;0u?MyBn}68#Pn7FV4UskHQVdzB+@?>K z`7-rHPxro;w`hY|Y(z?z{VlaN1DP%g1>-Xh^5boPO-WBweZ0t#)F(HK&To+FQ;Qt= zc~DALcQ8r}iG~0B>+qTm{SY3;oj0%(*Uhr{ni(R~H1KqEB4HfV+x*bdLabFc$;LaQcD?3(}kA3{@9+yDRo delta 936 zcmXBQOKeP07zgls?!7a2rZaPU>s2i}qo^_-z4x?q82a+4SKWFCk(me!MKl#5@tA0G zB;6nlC#{gP5E~n&^jl~ID~U}d)`G4i7DHG_Y5ixM| zy_{gD&Ei$Fg>MMo6n;SX!BO9`5>->0R!od?)B@@saA1lO=d8R@YeX=JB4nV00oY;U z{bmrX8$bJsLJ)>Bh(Hu#U_&`LPysVwCd`7_Fb67OE>uA^%!B!`0BRr(30MfVum~2z z5~zcvP!G#sIV52Ptb|pt8XCX_4>&YJ6Rd%?&}#=)>c%wfe%tcY z`rpf&gVylqrxx8oAl;R`k%qo|BQaU%H>>1$&w+<@rp7(Qia(`Gw@y#W%yc?L4L{Q3 zG5H|c6_bgCvrJxfBOz-4lzvfKY0%%#=}vYh7cCDrHa2mdO7UiS`@HUkhl*`D*fSxs zUyUPlxSv0Y-kqrIkeN%|mRE*6o1T30^wKdVo#^HFY}s&)uc37ro-EA<=tQ1RU+rQhlXo@aQVbcQA?HoHwU%=k%LPS?4I=~%(Dm{6@kwF%WO zREJQTgxW0B7NNEZ)hX0Ap|%UPL#UlX?Gma>sNF*OLUjwZN2t9*?GtLhPzQuM_z!k& BS0(@e diff --git a/anify-backend/src/index.ts b/anify-backend/src/index.ts index 978f05d..bb42f88 100644 --- a/anify-backend/src/index.ts +++ b/anify-backend/src/index.ts @@ -2,29 +2,15 @@ import dotenv from "dotenv"; dotenv.config(); import { fetchCorsProxies } from "./proxies/impl/fetchProxies"; -import { Format, MediaStatus, Type } from "./types/enums"; +import { MediaStatus } from "./types/enums"; import { init } from "./database"; import emitter, { Events } from "./lib"; import { get } from "./database/impl/modify/get"; import queues from "./worker"; import { start } from "./server"; -import { mangaProviders } from "./mappings"; -import { loadPDF } from "./lib/impl/pdf"; -import { loadMapping } from "./lib/impl/mappings"; -import { fetchChapters } from "./content/impl/chapters"; before().then(async (_) => { await start(); - const chapter = { - id: "/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1", - title: "Chapter 1", - number: 1, - updatedAt: 1660688888000, - }; - - //const pages = await mangaProviders.mangasee.fetchPages("/read-online/Mushoku-Tensei-Isekai-Ittara-Honki-Dasu-Shitsui-no-Majutsushihen-chapter-1"); - - //await loadPDF({ id: "dc481ed5-4925-4f3c-bac1-e73f1e7ed338", providerId: "mangasee", chapter, pages: pages ?? [] }).then(console.log); }); async function before() { diff --git a/anify-frontend/src/pages/login.tsx b/anify-frontend/src/pages/login.tsx index 536d2bc..1368dd2 100644 --- a/anify-frontend/src/pages/login.tsx +++ b/anify-frontend/src/pages/login.tsx @@ -98,7 +98,7 @@ const Login: NextPage = ({ login, user, token, provider, providers, redir