From 2ba7782f5d7117c586422893e33ba591ca30245a Mon Sep 17 00:00:00 2001 From: zimplexing Date: Sat, 26 Jul 2025 12:53:47 +0800 Subject: [PATCH] chore: delete backend --- backend/.env | 5 - backend/.env.example | 5 - backend/Dockerfile | 38 - backend/package.json | 26 - backend/src/config/config.json | 81 --- backend/src/config/index.ts | 80 --- backend/src/data/favorites.json | 1 - backend/src/data/playrecords.json | 1 - backend/src/data/searchhistory.json | 1 - backend/src/index.docker.ts | 28 - backend/src/index.ts | 24 - backend/src/routes/detail.ts | 156 ---- backend/src/routes/douban.ts | 161 ----- backend/src/routes/favorites.ts | 67 -- backend/src/routes/image-proxy.ts | 43 -- backend/src/routes/index.ts | 24 - backend/src/routes/login.ts | 58 -- backend/src/routes/playrecords.ts | 59 -- backend/src/routes/search.ts | 270 ------- backend/src/routes/searchhistory.ts | 66 -- backend/src/routes/server-config.ts | 38 - backend/src/types/index.ts | 28 - backend/src/utils/index.ts | 10 - backend/tsconfig.json | 14 - backend/vercel.json | 18 - backend/yarn.lock | 1025 --------------------------- 26 files changed, 2327 deletions(-) delete mode 100644 backend/.env delete mode 100644 backend/.env.example delete mode 100644 backend/Dockerfile delete mode 100644 backend/package.json delete mode 100644 backend/src/config/config.json delete mode 100644 backend/src/config/index.ts delete mode 100644 backend/src/data/favorites.json delete mode 100644 backend/src/data/playrecords.json delete mode 100644 backend/src/data/searchhistory.json delete mode 100644 backend/src/index.docker.ts delete mode 100644 backend/src/index.ts delete mode 100644 backend/src/routes/detail.ts delete mode 100644 backend/src/routes/douban.ts delete mode 100644 backend/src/routes/favorites.ts delete mode 100644 backend/src/routes/image-proxy.ts delete mode 100644 backend/src/routes/index.ts delete mode 100644 backend/src/routes/login.ts delete mode 100644 backend/src/routes/playrecords.ts delete mode 100644 backend/src/routes/search.ts delete mode 100644 backend/src/routes/searchhistory.ts delete mode 100644 backend/src/routes/server-config.ts delete mode 100644 backend/src/types/index.ts delete mode 100644 backend/src/utils/index.ts delete mode 100644 backend/tsconfig.json delete mode 100644 backend/vercel.json delete mode 100644 backend/yarn.lock diff --git a/backend/.env b/backend/.env deleted file mode 100644 index 81825a8..0000000 --- a/backend/.env +++ /dev/null @@ -1,5 +0,0 @@ -# The port the backend server will run on -PORT=3001 - -# Optional: The password for the login endpoint. If not provided, login is disabled. -PASSWORD= \ No newline at end of file diff --git a/backend/.env.example b/backend/.env.example deleted file mode 100644 index 81825a8..0000000 --- a/backend/.env.example +++ /dev/null @@ -1,5 +0,0 @@ -# The port the backend server will run on -PORT=3001 - -# Optional: The password for the login endpoint. If not provided, login is disabled. -PASSWORD= \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile deleted file mode 100644 index 80d1446..0000000 --- a/backend/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -# --- Build Stage --- -FROM node:18-alpine AS builder - -WORKDIR /app - -# Copy package.json and yarn.lock first to leverage Docker cache -COPY package.json yarn.lock ./ -RUN yarn install --frozen-lockfile - -# Copy the rest of the source code -COPY . . - -# Compile TypeScript to JavaScript -RUN yarn build - -# Prune development dependencies -RUN yarn install --production --ignore-scripts --prefer-offline - - -# --- Production Stage --- -FROM node:18-alpine - -WORKDIR /app - -# Copy production dependencies and compiled code from the builder stage -COPY --from=builder /app/node_modules ./node_modules -COPY --from=builder /app/dist ./dist - -# Copy config.json from the project root relative to the Docker build context -# IMPORTANT: When building, run `docker build -f backend/Dockerfile .` from the project root. -COPY src/config/config.json dist/config/ - -# Expose the port the app runs on -EXPOSE 3001 - -# The command to run the application -# You can override the port using -e PORT=... in `docker run` -CMD [ "node", "dist/index.docker.js" ] \ No newline at end of file diff --git a/backend/package.json b/backend/package.json deleted file mode 100644 index b5d4ec9..0000000 --- a/backend/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "OrionTV-proxy", - "version": "1.0.1", - "description": "Backend service for MyTV application", - "main": "dist/index.js", - "scripts": { - "start": "node dist/index.js", - "build": "tsc", - "dev": "ts-node-dev --respawn --transpile-only src/index.docker.ts" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "cors": "^2.8.5", - "express": "^4.19.2", - "dotenv": "^16.4.5" - }, - "devDependencies": { - "@types/cors": "^2.8.17", - "@types/express": "^4.17.21", - "@types/node": "^20.14.2", - "ts-node-dev": "^2.0.0", - "typescript": "^5.4.5" - } -} diff --git a/backend/src/config/config.json b/backend/src/config/config.json deleted file mode 100644 index dcdf585..0000000 --- a/backend/src/config/config.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "cache_time": 7200, - "api_site": { - "dyttzy": { - "api": "http://caiji.dyttzyapi.com/api.php/provide/vod", - "name": "电影天堂资源" - }, - "ruyi": { - "api": "https://cj.rycjapi.com/api.php/provide/vod", - "name": "如意资源" - }, - "mozhua": { - "api": "https://mozhuazy.com/api.php/provide/vod", - "name": "魔爪资源" - }, - "heimuer": { - "api": "https://json.heimuer.xyz/api.php/provide/vod", - "name": "黑木耳" - }, - "bfzy": { - "api": "https://bfzyapi.com/api.php/provide/vod", - "name": "暴风资源" - }, - "tyyszy": { - "api": "https://tyyszy.com/api.php/provide/vod", - "name": "天涯资源" - }, - "ffzy": { - "api": "http://ffzy5.tv/api.php/provide/vod", - "name": "非凡影视" - }, - "zy360": { - "api": "https://360zy.com/api.php/provide/vod", - "name": "360资源" - }, - "iqiyi": { - "api": "https://www.iqiyizyapi.com/api.php/provide/vod", - "name": "iqiyi资源" - }, - "wolong": { - "api": "https://wolongzyw.com/api.php/provide/vod", - "name": "卧龙资源" - }, - "hwba": { - "api": "https://cjhwba.com/api.php/provide/vod", - "name": "华为吧资源" - }, - "jisu": { - "api": "https://jszyapi.com/api.php/provide/vod", - "name": "极速资源" - }, - "dbzy": { - "api": "https://dbzy.tv/api.php/provide/vod", - "name": "豆瓣资源" - }, - "mdzy": { - "api": "https://www.mdzyapi.com/api.php/provide/vod", - "name": "魔都资源" - }, - "zuid": { - "api": "https://api.zuidapi.com/api.php/provide/vod", - "name": "最大资源" - }, - "yinghua": { - "api": "https://m3u8.apiyhzy.com/api.php/provide/vod", - "name": "樱花资源" - }, - "wujin": { - "api": "https://api.wujinapi.me/api.php/provide/vod", - "name": "无尽资源" - }, - "wwzy": { - "api": "https://wwzy.tv/api.php/provide/vod", - "name": "旺旺短剧" - }, - "ikun": { - "api": "https://ikunzyapi.com/api.php/provide/vod", - "name": "iKun资源" - } - } -} diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts deleted file mode 100644 index 2a713ed..0000000 --- a/backend/src/config/index.ts +++ /dev/null @@ -1,80 +0,0 @@ -import fs from "fs"; -import path from "path"; - -export interface ApiSite { - key: string; - api: string; - name: string; - detail?: string; -} - -export interface StorageConfig { - type: "localstorage" | "database"; - database?: { - host?: string; - port?: number; - username?: string; - password?: string; - database?: string; - }; -} - -export interface Config { - cache_time?: number; - api_site: { - [key: string]: ApiSite; - }; - storage?: StorageConfig; -} - -export const API_CONFIG = { - search: { - path: "?ac=videolist&wd=", - pagePath: "?ac=videolist&wd={query}&pg={page}", - headers: { - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", - Accept: "application/json", - }, - }, - detail: { - path: "?ac=videolist&ids=", - headers: { - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", - Accept: "application/json", - }, - }, -}; - -// Adjust path to read from project root, not from `backend/` -const configPath = path.join(__dirname, "config.json"); -let cachedConfig: Config; - -try { - cachedConfig = JSON.parse(fs.readFileSync(configPath, "utf-8")) as Config; -} catch (error) { - console.info(`Error reading or parsing config.json at ${configPath}`, error); - // Provide a default fallback config to prevent crashes - cachedConfig = { - api_site: {}, - cache_time: 300, - }; -} - -export function getConfig(): Config { - return cachedConfig; -} - -export function getCacheTime(): number { - const config = getConfig(); - return config.cache_time || 300; // 默认5分钟缓存 -} - -export function getApiSites(): ApiSite[] { - const config = getConfig(); - return Object.entries(config.api_site).map(([key, site]) => ({ - ...site, - key, - })); -} diff --git a/backend/src/data/favorites.json b/backend/src/data/favorites.json deleted file mode 100644 index 0967ef4..0000000 --- a/backend/src/data/favorites.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/backend/src/data/playrecords.json b/backend/src/data/playrecords.json deleted file mode 100644 index 9e26dfe..0000000 --- a/backend/src/data/playrecords.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/backend/src/data/searchhistory.json b/backend/src/data/searchhistory.json deleted file mode 100644 index fe51488..0000000 --- a/backend/src/data/searchhistory.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/backend/src/index.docker.ts b/backend/src/index.docker.ts deleted file mode 100644 index 56b7c19..0000000 --- a/backend/src/index.docker.ts +++ /dev/null @@ -1,28 +0,0 @@ -import express, { Express, Request, Response } from "express"; -import cors from "cors"; -import dotenv from "dotenv"; - -dotenv.config(); - -const app: Express = express(); -const port = process.env.PORT || 3001; - -// Middlewares -app.use(cors()); -app.use(express.json()); - -// Health check route -app.get("/", (req: Request, res: Response) => { - res.send("MyTV Backend Service is running!"); -}); - -import apiRouter from "./routes"; - -// API routes -app.use("/api", apiRouter); - -app.listen(port, () => { - console.log(`Server is running on port ${port}`); -}); - -export default app; diff --git a/backend/src/index.ts b/backend/src/index.ts deleted file mode 100644 index efa334e..0000000 --- a/backend/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import express, { Express, Request, Response } from "express"; -import cors from "cors"; -import dotenv from "dotenv"; - -dotenv.config(); - -const app: Express = express(); -const port = process.env.PORT || 3001; - -// Middlewares -app.use(cors()); -app.use(express.json()); - -// Health check route -app.get("/", (req: Request, res: Response) => { - res.send("MyTV Backend Service is running!"); -}); - -import apiRouter from "./routes"; - -// API routes -app.use("/api", apiRouter); - -export default app; diff --git a/backend/src/routes/detail.ts b/backend/src/routes/detail.ts deleted file mode 100644 index cb9b47a..0000000 --- a/backend/src/routes/detail.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { Router, Request, Response } from "express"; -import { API_CONFIG, ApiSite, getApiSites, getCacheTime } from "../config"; -import { VideoDetail } from "../types"; -import { cleanHtmlTags } from "../utils"; - -const router = Router(); - -// Match m3u8 links -const M3U8_PATTERN = /(https?:\/\/[^"'\s]+?\.m3u8)/g; - -async function handleSpecialSourceDetail(id: string, apiSite: ApiSite): Promise { - const detailUrl = `${apiSite.detail}/index.php/vod/detail/id/${id}.html`; - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), 10000); - - const response = await fetch(detailUrl, { - headers: API_CONFIG.detail.headers, - signal: controller.signal, - }); - clearTimeout(timeoutId); - - if (!response.ok) { - throw new Error(`详情页请求失败: ${response.status}`); - } - - const html = await response.text(); - let matches: string[] = []; - - if (apiSite.key === "ffzy") { - const ffzyPattern = /\$(https?:\/\/[^"'\s]+?\/\d{8}\/\d+_[a-f0-9]+\/index\.m3u8)/g; - matches = html.match(ffzyPattern) || []; - } - - if (matches.length === 0) { - const generalPattern = /\$(https?:\/\/[^"'\s]+?\.m3u8)/g; - matches = html.match(generalPattern) || []; - } - - matches = Array.from(new Set(matches)).map((link: string) => { - link = link.substring(1); - const parenIndex = link.indexOf("("); - return parenIndex > 0 ? link.substring(0, parenIndex) : link; - }); - - const titleMatch = html.match(/]*>([^<]+)<\/h1>/); - const titleText = titleMatch ? titleMatch[1].trim() : ""; - const descMatch = html.match(/]*class=["']sketch["'][^>]*>([\s\S]*?)<\/div>/); - const descText = descMatch ? cleanHtmlTags(descMatch[1]) : ""; - const coverMatch = html.match(/(https?:\/\/[^"'\s]+?\.jpg)/g); - const coverUrl = coverMatch ? coverMatch[0].trim() : ""; - - return { - id, - title: titleText, - poster: coverUrl, - desc: descText, - source_name: apiSite.name, - source: apiSite.key, - }; -} - -async function getDetailFromApi(apiSite: ApiSite, id: string): Promise { - const detailUrl = `${apiSite.api}${API_CONFIG.detail.path}${id}`; - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), 10000); - - const response = await fetch(detailUrl, { - headers: API_CONFIG.detail.headers, - signal: controller.signal, - }); - clearTimeout(timeoutId); - - if (!response.ok) { - throw new Error(`详情请求失败: ${response.status}`); - } - - const data = await response.json(); - if (!data || !data.list || !Array.isArray(data.list) || data.list.length === 0) { - throw new Error("获取到的详情内容无效"); - } - - const videoDetail = data.list[0]; - let episodes: string[] = []; - - if (videoDetail.vod_play_url) { - const playSources = videoDetail.vod_play_url.split("$$$"); - if (playSources.length > 0) { - const mainSource = playSources[0]; - const episodeList = mainSource.split("#"); - episodes = episodeList - .map((ep: string) => { - const parts = ep.split("$"); - return parts.length > 1 ? parts[1] : ""; - }) - .filter((url: string) => url && (url.startsWith("http://") || url.startsWith("https://"))); - } - } - - if (episodes.length === 0 && videoDetail.vod_content) { - const matches = videoDetail.vod_content.match(M3U8_PATTERN) || []; - episodes = matches.map((link: string) => link.replace(/^\$/, "")); - } - - return { - id, - title: videoDetail.vod_name, - poster: videoDetail.vod_pic, - desc: cleanHtmlTags(videoDetail.vod_content), - type: videoDetail.type_name, - year: videoDetail.vod_year?.match(/\d{4}/)?.[0] || "", - area: videoDetail.vod_area, - director: videoDetail.vod_director, - actor: videoDetail.vod_actor, - remarks: videoDetail.vod_remarks, - source_name: apiSite.name, - source: apiSite.key, - }; -} - -async function getVideoDetail(id: string, sourceCode: string): Promise { - if (!id) { - throw new Error("缺少视频ID参数"); - } - if (!/^[\w-]+$/.test(id)) { - throw new Error("无效的视频ID格式"); - } - const apiSites = getApiSites(); - const apiSite = apiSites.find((site) => site.key === sourceCode); - if (!apiSite) { - throw new Error("无效的API来源"); - } - if (apiSite.detail) { - return handleSpecialSourceDetail(id, apiSite); - } - return getDetailFromApi(apiSite, id); -} - -router.get("/", async (req: Request, res: Response) => { - const id = req.query.id as string; - const sourceCode = req.query.source as string; - - if (!id || !sourceCode) { - return res.status(400).json({ error: "缺少必要参数" }); - } - - try { - const result = await getVideoDetail(id, sourceCode); - const cacheTime = getCacheTime(); - res.setHeader("Cache-Control", `public, max-age=${cacheTime}`); - res.json(result); - } catch (error) { - res.status(500).json({ error: (error as Error).message }); - } -}); - -export default router; diff --git a/backend/src/routes/douban.ts b/backend/src/routes/douban.ts deleted file mode 100644 index 829eb70..0000000 --- a/backend/src/routes/douban.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { Router, Request, Response } from "express"; -import { getCacheTime } from "../config"; - -const router = Router(); - -// --- Interfaces --- -interface DoubanItem { - title: string; - poster: string; - rate: string; -} - -interface DoubanResponse { - code: number; - message: string; - list: DoubanItem[]; -} - -interface DoubanApiResponse { - subjects: Array<{ - title: string; - cover: string; - rate: string; - }>; -} - -// --- Helper Functions --- - -async function fetchDoubanData(url: string): Promise { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), 10000); - - const fetchOptions = { - signal: controller.signal, - headers: { - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36", - Referer: "https://movie.douban.com/", - Accept: "application/json, text/plain, */*", - }, - }; - - try { - const response = await fetch(url, fetchOptions); - clearTimeout(timeoutId); - if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); - } - return await response.json(); - } catch (error) { - clearTimeout(timeoutId); - throw error; - } -} - -async function handleTop250(pageStart: number, res: Response) { - const target = `https://movie.douban.com/top250?start=${pageStart}&filter=`; - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), 10000); - - const fetchOptions = { - signal: controller.signal, - headers: { - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36", - Referer: "https://movie.douban.com/", - Accept: - "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", - }, - }; - - try { - const fetchResponse = await fetch(target, fetchOptions); - clearTimeout(timeoutId); - - if (!fetchResponse.ok) { - throw new Error(`HTTP error! Status: ${fetchResponse.status}`); - } - - const html = await fetchResponse.text(); - const moviePattern = - /
[\s\S]*?]+alt="([^"]+)"[^>]*src="([^"]+)"[\s\S]*?]*>([^<]+)<\/span>[\s\S]*?<\/div>/g; - const movies: DoubanItem[] = []; - let match; - - while ((match = moviePattern.exec(html)) !== null) { - const title = match[1]; - const cover = match[2]; - const rate = match[3] || ""; - const processedCover = cover.replace(/^http:/, "https:"); - movies.push({ title, poster: processedCover, rate }); - } - - const apiResponse: DoubanResponse = { - code: 200, - message: "获取成功", - list: movies, - }; - const cacheTime = getCacheTime(); - res.setHeader("Cache-Control", `public, max-age=${cacheTime}`); - res.json(apiResponse); - } catch (error) { - clearTimeout(timeoutId); - res.status(500).json({ - error: "获取豆瓣 Top250 数据失败", - details: (error as Error).message, - }); - } -} - -// --- Main Route Handler --- - -router.get("/", async (req: Request, res: Response) => { - const { type, tag } = req.query; - const pageSize = parseInt((req.query.pageSize as string) || "16"); - const pageStart = parseInt((req.query.pageStart as string) || "0"); - - if (!type || !tag) { - return res.status(400).json({ error: "缺少必要参数: type 或 tag" }); - } - if (typeof type !== "string" || !["tv", "movie"].includes(type)) { - return res.status(400).json({ error: "type 参数必须是 tv 或 movie" }); - } - if (pageSize < 1 || pageSize > 100) { - return res.status(400).json({ error: "pageSize 必须在 1-100 之间" }); - } - if (pageStart < 0) { - return res.status(400).json({ error: "pageStart 不能小于 0" }); - } - - if (tag === "top250") { - return handleTop250(pageStart, res); - } - - const target = `https://movie.douban.com/j/search_subjects?type=${type}&tag=${tag}&sort=recommend&page_limit=${pageSize}&page_start=${pageStart}`; - - try { - const doubanData = await fetchDoubanData(target); - const list: DoubanItem[] = doubanData.subjects.map((item) => ({ - title: item.title, - poster: item.cover, - rate: item.rate, - })); - - const response: DoubanResponse = { - code: 200, - message: "获取成功", - list: list, - }; - const cacheTime = getCacheTime(); - res.setHeader("Cache-Control", `public, max-age=${cacheTime}`); - res.json(response); - } catch (error) { - res.status(500).json({ - error: "获取豆瓣数据失败", - details: (error as Error).message, - }); - } -}); - -export default router; diff --git a/backend/src/routes/favorites.ts b/backend/src/routes/favorites.ts deleted file mode 100644 index c7fa2fe..0000000 --- a/backend/src/routes/favorites.ts +++ /dev/null @@ -1,67 +0,0 @@ -import express, { Request, Response } from "express"; -import fs from "fs/promises"; -import path from "path"; - -const router = express.Router(); -const dataPath = path.join(__dirname, "..", "data", "favorites.json"); - -// Helper function to read data -const readFavorites = async () => { - try { - const data = await fs.readFile(dataPath, "utf-8"); - return JSON.parse(data); - } catch (error) { - // If file doesn't exist or is invalid json, return empty object - return {}; - } -}; - -// Helper function to write data -const writeFavorites = async (data: any) => { - await fs.writeFile(dataPath, JSON.stringify(data, null, 2), "utf-8"); -}; - -// GET /api/favorites -router.get("/favorites", async (req: Request, res: Response) => { - const { key } = req.query; - const favorites = await readFavorites(); - - if (key) { - res.json(favorites[key as string] || null); - } else { - res.json(favorites); - } -}); - -// POST /api/favorites -router.post("/favorites", async (req: Request, res: Response) => { - const { key, favorite } = req.body; - - if (!key || !favorite) { - return res.status(400).json({ message: "Missing key or favorite data" }); - } - - const favorites = await readFavorites(); - favorites[key] = { ...favorite, save_time: Math.floor(Date.now() / 1000) }; - await writeFavorites(favorites); - - res.json({ success: true }); -}); - -// DELETE /api/favorites -router.delete("/favorites", async (req: Request, res: Response) => { - const { key } = req.query; - let favorites = await readFavorites(); - - if (key) { - delete favorites[key as string]; - } else { - // Clear all favorites if no key is provided - favorites = {}; - } - - await writeFavorites(favorites); - res.json({ success: true }); -}); - -export default router; diff --git a/backend/src/routes/image-proxy.ts b/backend/src/routes/image-proxy.ts deleted file mode 100644 index 9c8d4b6..0000000 --- a/backend/src/routes/image-proxy.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Router, Request, Response } from "express"; -import { Readable } from "node:stream"; - -const router = Router(); - -router.get("/", async (req: Request, res: Response) => { - const imageUrl = req.query.url as string; - - if (!imageUrl) { - return res.status(400).send("Missing image URL"); - } - - try { - const imageResponse = await fetch(imageUrl, { - headers: { - Referer: "https://movie.douban.com/", - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36", - }, - }); - - if (!imageResponse.ok) { - return res.status(imageResponse.status).send(imageResponse.statusText); - } - - const contentType = imageResponse.headers.get("content-type"); - if (contentType) { - res.setHeader("Content-Type", contentType); - } - - if (imageResponse.body) { - const nodeStream = Readable.fromWeb(imageResponse.body as any); - nodeStream.pipe(res); - } else { - res.status(500).send("Image response has no body"); - } - } catch (error) { - console.info("Image proxy error:", error); - res.status(500).send("Error fetching image"); - } -}); - -export default router; diff --git a/backend/src/routes/index.ts b/backend/src/routes/index.ts deleted file mode 100644 index b0b455f..0000000 --- a/backend/src/routes/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Router } from "express"; -import searchRouter from "./search"; -import detailRouter from "./detail"; -import doubanRouter from "./douban"; -import imageProxyRouter from "./image-proxy"; -import serverConfigRouter from "./server-config"; -import loginRouter from "./login"; -import favoritesRouter from "./favorites"; -import playRecordsRouter from "./playrecords"; -import searchHistoryRouter from "./searchhistory"; - -const router = Router(); - -router.use(serverConfigRouter); -router.use(loginRouter); -router.use(favoritesRouter); -router.use(playRecordsRouter); -router.use(searchHistoryRouter); -router.use("/search", searchRouter); -router.use("/detail", detailRouter); -router.use("/douban", doubanRouter); -router.use("/image-proxy", imageProxyRouter); - -export default router; diff --git a/backend/src/routes/login.ts b/backend/src/routes/login.ts deleted file mode 100644 index 3555417..0000000 --- a/backend/src/routes/login.ts +++ /dev/null @@ -1,58 +0,0 @@ -import express, { Request, Response } from "express"; -import dotenv from "dotenv"; - -dotenv.config(); - -const router = express.Router(); -const username = process.env.USERNAME; -const password = process.env.PASSWORD; - -/** - * @api {post} /api/login User Login - * @apiName UserLogin - * @apiGroup User - * - * @apiBody {String} username User's username. - * @apiBody {String} password User's password. - * - * @apiSuccess {Boolean} ok Indicates if the login was successful. - * - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * { - * "ok": true - * } - * - * @apiError {String} message Error message. - * - * @apiErrorExample {json} Error-Response: - * HTTP/1.1 400 Bad Request - * { - * "message": "Invalid password" - * } - */ -router.post("/login", (req: Request, res: Response) => { - const { username: inputUsername, password: inputPassword } = req.body; - - // Compatibility with old versions, if username is not set, only password is required - if (!username || !password) { - if (inputPassword === password) { - res.cookie("auth", "true", { httpOnly: true, maxAge: 24 * 60 * 60 * 1000 }); - return res.json({ ok: true }); - } else if (!password) { - // If no password is set, login is always successful. - return res.json({ ok: true }); - } else { - return res.status(400).json({ message: "Invalid password" }); - } - } - - if (inputUsername === username && inputPassword === password) { - res.cookie("auth", "true", { httpOnly: true, maxAge: 24 * 60 * 60 * 1000 }); - res.json({ ok: true }); - } else { - res.status(400).json({ message: "Invalid username or password" }); - } -}); - -export default router; diff --git a/backend/src/routes/playrecords.ts b/backend/src/routes/playrecords.ts deleted file mode 100644 index 43f6255..0000000 --- a/backend/src/routes/playrecords.ts +++ /dev/null @@ -1,59 +0,0 @@ -import express, { Request, Response } from "express"; -import fs from "fs/promises"; -import path from "path"; - -const router = express.Router(); -const dataPath = path.join(__dirname, "..", "data", "playrecords.json"); - -// Helper function to read data -const readPlayRecords = async () => { - try { - const data = await fs.readFile(dataPath, "utf-8"); - return JSON.parse(data); - } catch (error) { - return {}; - } -}; - -// Helper function to write data -const writePlayRecords = async (data: any) => { - await fs.writeFile(dataPath, JSON.stringify(data, null, 2), "utf-8"); -}; - -// GET /api/playrecords -router.get("/playrecords", async (req: Request, res: Response) => { - const records = await readPlayRecords(); - res.json(records); -}); - -// POST /api/playrecords -router.post("/playrecords", async (req: Request, res: Response) => { - const { key, record } = req.body; - - if (!key || !record) { - return res.status(400).json({ message: "Missing key or record data" }); - } - - const records = await readPlayRecords(); - records[key] = { ...record, time: Math.floor(Date.now() / 1000) }; - await writePlayRecords(records); - - res.json({ success: true }); -}); - -// DELETE /api/playrecords -router.delete("/playrecords", async (req: Request, res: Response) => { - const { key } = req.query; - let records = await readPlayRecords(); - - if (key) { - delete records[key as string]; - } else { - records = {}; - } - - await writePlayRecords(records); - res.json({ success: true }); -}); - -export default router; diff --git a/backend/src/routes/search.ts b/backend/src/routes/search.ts deleted file mode 100644 index ec47b87..0000000 --- a/backend/src/routes/search.ts +++ /dev/null @@ -1,270 +0,0 @@ -import { Router, Request, Response } from "express"; -import { API_CONFIG, ApiSite, getApiSites, getCacheTime } from "../config"; -import { cleanHtmlTags } from "../utils"; - -const router = Router(); - -// 根据环境变量决定最大搜索页数,默认 5 -const MAX_SEARCH_PAGES: number = Number(process.env.SEARCH_MAX_PAGE) || 5; - -export interface SearchResult { - id: string; - title: string; - poster: string; - episodes: string[]; - source: string; - source_name: string; - class?: string; - year: string; - desc?: string; - type_name?: string; -} - -interface ApiSearchItem { - vod_id: string; - vod_name: string; - vod_pic: string; - vod_remarks?: string; - vod_play_url?: string; - vod_class?: string; - vod_year?: string; - vod_content?: string; - type_name?: string; -} - -async function searchFromApi( - apiSite: ApiSite, - query: string -): Promise { - try { - const apiBaseUrl = apiSite.api; - const apiUrl = - apiBaseUrl + API_CONFIG.search.path + encodeURIComponent(query); - const apiName = apiSite.name; - - // 添加超时处理 - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), 8000); - - const response = await fetch(apiUrl, { - headers: API_CONFIG.search.headers, - signal: controller.signal, - }); - - clearTimeout(timeoutId); - - if (!response.ok) { - return []; - } - - const data = await response.json(); - - console.log( - "apiUrl", - apiSite.name, - "response status", - response.ok, - "response data", - data.list.length - ); - - if ( - !data || - !data.list || - !Array.isArray(data.list) || - data.list.length === 0 - ) { - return []; - } - // 处理第一页结果 - const results = data.list.map((item: ApiSearchItem) => { - let episodes: string[] = []; - - // 使用正则表达式从 vod_play_url 提取 m3u8 链接 - if (item.vod_play_url) { - const m3u8Regex = /\$(https?:\/\/[^"'\s]+?\.m3u8)/g; - // 先用 $$$ 分割 - const vod_play_url_array = item.vod_play_url.split("$$$"); - // 对每个分片做匹配,取匹配到最多的作为结果 - vod_play_url_array.forEach((url: string) => { - const matches = url.match(m3u8Regex) || []; - if (matches.length > episodes.length) { - episodes = matches; - } - }); - } - - episodes = Array.from(new Set(episodes)).map((link: string) => { - link = link.substring(1); // 去掉开头的 $ - const parenIndex = link.indexOf("("); - return parenIndex > 0 ? link.substring(0, parenIndex) : link; - }); - - return { - id: item.vod_id, - title: item.vod_name, - poster: item.vod_pic, - episodes, - source: apiSite.key, - source_name: apiName, - class: item.vod_class, - year: item.vod_year ? item.vod_year.match(/\d{4}/)?.[0] || "" : "", - desc: cleanHtmlTags(item.vod_content || ""), - type_name: item.type_name, - }; - }); - - // 获取总页数 - const pageCount = data.pagecount || 1; - // 确定需要获取的额外页数 - const pagesToFetch = Math.min(pageCount - 1, MAX_SEARCH_PAGES - 1); - - // 如果有额外页数,获取更多页的结果 - if (pagesToFetch > 0) { - const additionalPagePromises = []; - - for (let page = 2; page <= pagesToFetch + 1; page++) { - const pageUrl = - apiBaseUrl + - API_CONFIG.search.pagePath - .replace("{query}", encodeURIComponent(query)) - .replace("{page}", page.toString()); - - const pagePromise = (async () => { - try { - const pageController = new AbortController(); - const pageTimeoutId = setTimeout( - () => pageController.abort(), - 8000 - ); - - const pageResponse = await fetch(pageUrl, { - headers: API_CONFIG.search.headers, - signal: pageController.signal, - }); - - clearTimeout(pageTimeoutId); - - if (!pageResponse.ok) return []; - - const pageData = await pageResponse.json(); - - if (!pageData || !pageData.list || !Array.isArray(pageData.list)) - return []; - - return pageData.list.map((item: ApiSearchItem) => { - let episodes: string[] = []; - - if (item.vod_play_url) { - const m3u8Regex = /\$(https?:\/\/[^"'\s]+?\.m3u8)/g; - episodes = item.vod_play_url.match(m3u8Regex) || []; - } - - episodes = Array.from(new Set(episodes)).map((link: string) => { - link = link.substring(1); // 去掉开头的 $ - const parenIndex = link.indexOf("("); - return parenIndex > 0 ? link.substring(0, parenIndex) : link; - }); - - return { - id: item.vod_id, - title: item.vod_name, - poster: item.vod_pic, - episodes, - source: apiSite.key, - source_name: apiName, - class: item.vod_class, - year: item.vod_year - ? item.vod_year.match(/\d{4}/)?.[0] || "" - : "", - desc: cleanHtmlTags(item.vod_content || ""), - type_name: item.type_name, - }; - }); - } catch (error) { - return []; - } - })(); - - additionalPagePromises.push(pagePromise); - } - - const additionalResults = await Promise.all(additionalPagePromises); - - additionalResults.forEach((pageResults) => { - if (pageResults.length > 0) { - results.push(...pageResults); - } - }); - } - - return results; - } catch (error) { - return []; - } -} - -router.get("/", async (req: Request, res: Response) => { - const query = req.query.q as string; - - if (!query) { - const cacheTime = getCacheTime(); - res.setHeader("Cache-Control", `public, max-age=${cacheTime}`); - return res.json({ results: [] }); - } - - const apiSites = getApiSites(); - const searchPromises = apiSites.map((site) => searchFromApi(site, query)); - - try { - const results = await Promise.all(searchPromises); - const flattenedResults = results.flat(); - const cacheTime = getCacheTime(); - - res.setHeader("Cache-Control", `public, max-age=${cacheTime}`); - res.json({ results: flattenedResults }); - } catch (error) { - res.status(500).json({ error: "搜索失败" }); - } -}); - -// 按资源 url 单个获取数据 -router.get("/one", async (req: Request, res: Response) => { - const { resourceId, q } = req.query; - - if (!resourceId || !q) { - return res.status(400).json({ error: "resourceId and q are required" }); - } - - const apiSites = getApiSites(); - const apiSite = apiSites.find((site) => site.key === (resourceId as string)); - - if (!apiSite) { - return res.status(404).json({ error: "Resource not found" }); - } - - try { - const results = await searchFromApi(apiSite, q as string); - const result = results.filter((r) => r.title === (q as string)); - - if (results) { - const cacheTime = getCacheTime(); - res.setHeader("Cache-Control", `public, max-age=${cacheTime}`); - res.json({results: result}); - } else { - res.status(404).json({ error: "Resource not found with the given query" }); - } - } catch (error) { - res.status(500).json({ error: "Failed to fetch resource details" }); - } -}); - -// 获取所有可用的资源列表 -router.get("/resources", async (req: Request, res: Response) => { - const apiSites = getApiSites(); - const cacheTime = getCacheTime(); - res.setHeader("Cache-Control", `public, max-age=${cacheTime}`); - res.json(apiSites); -}); - -export default router; diff --git a/backend/src/routes/searchhistory.ts b/backend/src/routes/searchhistory.ts deleted file mode 100644 index f814018..0000000 --- a/backend/src/routes/searchhistory.ts +++ /dev/null @@ -1,66 +0,0 @@ -import express, { Request, Response } from "express"; -import fs from "fs/promises"; -import path from "path"; - -const router = express.Router(); -const dataPath = path.join(__dirname, "..", "data", "searchhistory.json"); - -// Helper function to read data -const readSearchHistory = async (): Promise => { - try { - const data = await fs.readFile(dataPath, "utf-8"); - return JSON.parse(data); - } catch (error) { - return []; - } -}; - -// Helper function to write data -const writeSearchHistory = async (data: string[]) => { - await fs.writeFile(dataPath, JSON.stringify(data, null, 2), "utf-8"); -}; - -// GET /api/searchhistory -router.get("/searchhistory", async (req: Request, res: Response) => { - const history = await readSearchHistory(); - res.json(history); -}); - -// POST /api/searchhistory -router.post("/searchhistory", async (req: Request, res: Response) => { - const { keyword } = req.body; - - if (!keyword) { - return res.status(400).json({ message: "Missing keyword" }); - } - - let history = await readSearchHistory(); - // Remove keyword if it already exists to move it to the front - history = history.filter((item) => item !== keyword); - // Add to the beginning of the array - history.unshift(keyword); - // Optional: Limit history size - if (history.length > 100) { - history = history.slice(0, 100); - } - - await writeSearchHistory(history); - res.json(history); -}); - -// DELETE /api/searchhistory -router.delete("/searchhistory", async (req: Request, res: Response) => { - const { keyword } = req.query; - let history = await readSearchHistory(); - - if (keyword) { - history = history.filter((item) => item !== keyword); - } else { - history = []; - } - - await writeSearchHistory(history); - res.json({ success: true }); -}); - -export default router; diff --git a/backend/src/routes/server-config.ts b/backend/src/routes/server-config.ts deleted file mode 100644 index fd06fce..0000000 --- a/backend/src/routes/server-config.ts +++ /dev/null @@ -1,38 +0,0 @@ -import express, { Request, Response } from "express"; -import { getConfig } from "../config"; - -const router = express.Router(); - -/** - * @api {get} /api/server-config Get Server Configuration - * @apiName GetServerConfig - * @apiGroup Server - * - * @apiSuccess {String} SiteName The name of the site. - * @apiSuccess {String} StorageType The storage type used by the server ("localstorage" or "database"). - * - * @apiSuccessExample {json} Success-Response (LocalStorage): - * HTTP/1.1 200 OK - * { - * "SiteName": "OrionTV-Local", - * "StorageType": "localstorage" - * } - * - * @apiSuccessExample {json} Success-Response (Database): - * HTTP/1.1 200 OK - * { - * "SiteName": "OrionTV-Cloud", - * "StorageType": "database" - * } - */ -router.get("/server-config", (req: Request, res: Response) => { - const config = getConfig(); - const storageType = config.storage?.type || "database"; // Default to 'database' if not specified - - res.json({ - SiteName: storageType === "localstorage" ? "OrionTV-Local" : "OrionTV-Cloud", - StorageType: storageType, - }); -}); - -export default router; diff --git a/backend/src/types/index.ts b/backend/src/types/index.ts deleted file mode 100644 index 4d67937..0000000 --- a/backend/src/types/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Data structure for play records -export interface PlayRecord { - title: string; - source_name: string; - poster: string; - index: number; // Episode number - total_episodes: number; // Total number of episodes - play_time: number; // Play progress in seconds - total_time: number; // Total duration in seconds - save_time: number; // Timestamp of when the record was saved - user_id: number; // User ID, always 0 in this version -} - -// You can add other shared types here -export interface VideoDetail { - id: string; - title: string; - poster: string; - source: string; - source_name: string; - desc?: string; - type?: string; - year?: string; - area?: string; - director?: string; - actor?: string; - remarks?: string; -} diff --git a/backend/src/utils/index.ts b/backend/src/utils/index.ts deleted file mode 100644 index e4c153d..0000000 --- a/backend/src/utils/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export function cleanHtmlTags(text: string): string { - if (!text) return ""; - return text - .replace(/<[^>]+>/g, "\n") // 将 HTML 标签替换为换行 - .replace(/\n+/g, "\n") // 将多个连续换行合并为一个 - .replace(/[ \t]+/g, " ") // 将多个连续空格和制表符合并为一个空格,但保留换行符 - .replace(/^\n+|\n+$/g, "") // 去掉首尾换行 - .replace(/ /g, " ") // 将   替换为空格 - .trim(); // 去掉首尾空格 -} diff --git a/backend/tsconfig.json b/backend/tsconfig.json deleted file mode 100644 index e2082c5..0000000 --- a/backend/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "module": "CommonJS", - "rootDir": "./src", - "outDir": "./dist", - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "skipLibCheck": true - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "**/*.spec.ts"] -} diff --git a/backend/vercel.json b/backend/vercel.json deleted file mode 100644 index a5afa2e..0000000 --- a/backend/vercel.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": 2, - "builds": [ - { - "src": "src/index.ts", - "use": "@vercel/node", - "config": { - "includeFiles": ["./config.json"] - } - } - ], - "routes": [ - { - "src": "/(.*)", - "dest": "src/index.ts" - } - ] -} diff --git a/backend/yarn.lock b/backend/yarn.lock deleted file mode 100644 index d65c895..0000000 --- a/backend/yarn.lock +++ /dev/null @@ -1,1025 +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.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@jridgewell/resolve-uri@^3.0.3": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" - integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@tsconfig/node10@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" - integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" - integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== - -"@types/body-parser@*": - version "1.19.6" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.6.tgz#1859bebb8fd7dac9918a45d54c1971ab8b5af474" - integrity sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" - integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== - dependencies: - "@types/node" "*" - -"@types/cors@^2.8.17": - version "2.8.19" - resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.19.tgz#d93ea2673fd8c9f697367f5eeefc2bbfa94f0342" - integrity sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg== - dependencies: - "@types/node" "*" - -"@types/express-serve-static-core@^4.17.33": - version "4.19.6" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz#e01324c2a024ff367d92c66f48553ced0ab50267" - integrity sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express@^4.17.21": - version "4.17.23" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.23.tgz#35af3193c640bfd4d7fe77191cd0ed411a433bef" - integrity sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/http-errors@*": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" - integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== - -"@types/mime@^1": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" - integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== - -"@types/node@*": - version "24.0.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.0.4.tgz#dbae889912bda33a7f57669fb8587c1a56bc0c1f" - integrity sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA== - dependencies: - undici-types "~7.8.0" - -"@types/node@^20.14.2": - version "20.19.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.1.tgz#cef8bc04aaae86824b5bbe2570769358592bcc59" - integrity sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA== - dependencies: - undici-types "~6.21.0" - -"@types/qs@*": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.14.0.tgz#d8b60cecf62f2db0fb68e5e006077b9178b85de5" - integrity sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ== - -"@types/range-parser@*": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" - integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== - -"@types/send@*": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.5.tgz#d991d4f2b16f2b1ef497131f00a9114290791e74" - integrity sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/serve-static@*": - version "1.15.8" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.8.tgz#8180c3fbe4a70e8f00b9f70b9ba7f08f35987877" - integrity sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg== - dependencies: - "@types/http-errors" "*" - "@types/node" "*" - "@types/send" "*" - -"@types/strip-bom@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" - integrity sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ== - -"@types/strip-json-comments@0.0.30": - version "0.0.30" - resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" - integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== - -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-walk@^8.1.1: - version "8.3.4" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" - integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== - dependencies: - acorn "^8.11.0" - -acorn@^8.11.0, acorn@^8.4.1: - version "8.15.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" - integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - 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.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -binary-extensions@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" - integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== - -body-parser@1.20.3: - version "1.20.3" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" - integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== - dependencies: - bytes "3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.13.0" - raw-body "2.5.2" - type-is "~1.6.18" - unpipe "1.0.0" - -brace-expansion@^1.1.7: - version "1.1.12" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" - integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@~3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" - integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== - dependencies: - fill-range "^7.1.1" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" - integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - -call-bound@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" - integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== - dependencies: - call-bind-apply-helpers "^1.0.2" - get-intrinsic "^1.3.0" - -chokidar@^3.5.1: - version "3.6.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" - integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== - 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" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - 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.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" - integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== - -cors@^2.8.5: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - 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.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dotenv@^16.4.5: - version "16.6.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.6.0.tgz#b96bd4e7c2043ba5f51cbe1b8f9347850c864850" - integrity sha512-Omf1L8paOy2VJhILjyhrhqwLIdstqm1BvcDPKg4NGAlkwEu9ODyrFbvk8UymUOMCT+HXo31jg1lArIrVAAhuGA== - -dunder-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" - integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== - dependencies: - call-bind-apply-helpers "^1.0.1" - es-errors "^1.3.0" - gopd "^1.2.0" - -dynamic-dedupe@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz#06e44c223f5e4e94d78ef9db23a6515ce2f962a1" - integrity sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ== - dependencies: - xtend "^4.0.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -encodeurl@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" - integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== - -es-define-property@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" - integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== - -es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - -es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" - integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== - dependencies: - es-errors "^1.3.0" - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -express@^4.19.2: - version "4.21.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32" - integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.3" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.7.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.3.1" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.3" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.12" - proxy-addr "~2.0.7" - qs "6.13.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.19.0" - serve-static "1.16.2" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -fill-range@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" - integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" - integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== - dependencies: - debug "2.6.9" - encodeurl "~2.0.0" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" - integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== - dependencies: - call-bind-apply-helpers "^1.0.2" - es-define-property "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.1.1" - function-bind "^1.1.2" - get-proto "^1.0.1" - gopd "^1.2.0" - has-symbols "^1.1.0" - hasown "^2.0.2" - math-intrinsics "^1.1.0" - -get-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" - integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== - dependencies: - dunder-proto "^1.0.1" - es-object-atoms "^1.0.0" - -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - 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" - -gopd@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" - integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== - -has-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" - integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== - -hasown@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== - dependencies: - function-bind "^1.1.2" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - 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.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-core-module@^2.16.0: - version "2.16.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" - integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== - dependencies: - hasown "^2.0.2" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -math-intrinsics@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" - integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -merge-descriptors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" - integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -object-assign@^4: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.13.3: - version "1.13.4" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" - integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" - integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -qs@6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" - integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== - dependencies: - side-channel "^1.0.6" - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - 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" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -resolve@^1.0.0: - version "1.22.10" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" - integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== - dependencies: - is-core-module "^2.16.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -rimraf@^2.6.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -send@0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" - integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== - 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.16.2: - version "1.16.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" - integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== - dependencies: - encodeurl "~2.0.0" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.19.0" - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -side-channel-list@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" - integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.3" - -side-channel-map@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" - integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - -side-channel-weakmap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" - integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - side-channel-map "^1.0.1" - -side-channel@^1.0.6: - version "1.1.0" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" - integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.3" - side-channel-list "^1.0.0" - side-channel-map "^1.0.1" - side-channel-weakmap "^1.0.2" - -source-map-support@^0.5.12: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-json-comments@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tree-kill@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" - integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== - -ts-node-dev@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ts-node-dev/-/ts-node-dev-2.0.0.tgz#bdd53e17ab3b5d822ef519928dc6b4a7e0f13065" - integrity sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w== - dependencies: - chokidar "^3.5.1" - dynamic-dedupe "^0.3.0" - minimist "^1.2.6" - mkdirp "^1.0.4" - resolve "^1.0.0" - rimraf "^2.6.1" - source-map-support "^0.5.12" - tree-kill "^1.2.2" - ts-node "^10.4.0" - tsconfig "^7.0.0" - -ts-node@^10.4.0: - version "10.9.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" - integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== - 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@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7" - integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw== - dependencies: - "@types/strip-bom" "^3.0.0" - "@types/strip-json-comments" "0.0.30" - strip-bom "^3.0.0" - strip-json-comments "^2.0.0" - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typescript@^5.4.5: - version "5.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" - integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== - -undici-types@~6.21.0: - version "6.21.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" - integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== - -undici-types@~7.8.0: - version "7.8.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.8.0.tgz#de00b85b710c54122e44fbfd911f8d70174cd294" - integrity sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==