├── _config.temp.yml ├── src ├── tvbox │ ├── index.ts │ └── utils.ts ├── checker │ ├── index.ts │ └── caniuse.ts ├── task │ ├── env │ │ ├── index.ts │ │ ├── handler.ts │ │ └── define.ts │ ├── custom │ │ ├── index.ts │ │ ├── define.ts │ │ └── handler.ts │ └── const.ts ├── epgs │ ├── utils.ts │ └── index.ts ├── utils │ ├── index.ts │ ├── logo.ts │ ├── id.ts │ ├── trim.ts │ ├── m3u2txt.ts │ ├── collector.ts │ ├── from.ts │ ├── handlers.ts │ └── const.ts ├── sources │ ├── cymz6_lives.ts │ ├── yuechan_live.ts │ ├── yang_m3u.ts │ ├── index.ts │ ├── joevess_iptv.ts │ ├── fanmingming_live.ts │ ├── utils.ts │ ├── qwerttvv_bj_iptv.ts │ ├── epg_pw.ts │ └── iptv_org.ts ├── channels.ts ├── matrix.ts ├── rollback.ts ├── serve.ts ├── file.ts ├── readme.ts └── index.ts ├── .editorconfig ├── update-sources.sh ├── start-iptv.sh ├── iptv-update.sh ├── .gitignore ├── Dockerfile ├── LIST.temp.md ├── .dockerignore ├── .github ├── FUNDING.yml ├── dependabot.yml ├── ISSUE_TEMPLATE │ ├── 加入源镜像站-join-as-sources.md │ ├── 问题反馈-bug-report.md │ └── 新的特性功能-feature-request.md └── workflows │ ├── docker.yml │ ├── deploy.yml │ └── schedule.yml ├── tsup.config.ts ├── update-image.sh ├── .yarnclean ├── scripts └── release.js ├── README.temp.md ├── package.json ├── README.md ├── public └── check.html ├── LICENSE └── yarn.lock /_config.temp.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /src/tvbox/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./utils" -------------------------------------------------------------------------------- /src/checker/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./caniuse" -------------------------------------------------------------------------------- /src/task/env/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./handler" -------------------------------------------------------------------------------- /src/task/custom/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./handler" -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.yml] 2 | tab_width = 2 3 | indent_size = 2 4 | indent_style = space 5 | -------------------------------------------------------------------------------- /update-sources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cp -r ./m3u ./back && yarn m3u && rm -rf ./back 4 | -------------------------------------------------------------------------------- /start-iptv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | yarn install && yarn build && yarn m3u && yarn serve 4 | -------------------------------------------------------------------------------- /iptv-update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 执行内部更新命令 4 | docker exec -d iptv-sources /bin/sh ./update-sources.sh 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | 5 | test_* 6 | m3u 7 | back 8 | 9 | .env 10 | config -------------------------------------------------------------------------------- /src/epgs/utils.ts: -------------------------------------------------------------------------------- 1 | import type { ISource } from "../sources/utils" 2 | 3 | export type TEPGSource = Omit 4 | 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | 3 | WORKDIR /app 4 | COPY . /app 5 | 6 | EXPOSE 8080 7 | 8 | CMD [ "/bin/sh", "./start-iptv.sh" ] 9 | -------------------------------------------------------------------------------- /LIST.temp.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | | No. | Channel Name | From | Source | 4 | | --- | ------------ | ---- | ------ | 5 | 6 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .github 3 | .env 4 | 5 | node_modules 6 | dist 7 | test_* 8 | m3u 9 | back 10 | 11 | _config.temp.yml 12 | .editorconfig 13 | config -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: HerbertHe 4 | custom: ['https://afdian.net/a/HerbertHe', 'https://sponsor.ibert.me/'] 5 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./handlers" 2 | export * from "./const" 3 | export * from "./logo" 4 | export * from "./from" 5 | export * from "./collector" 6 | export * from "./id" 7 | export * from "./m3u2txt" 8 | export * from "./trim" -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup" 2 | 3 | export const tsup = defineConfig({ 4 | entry: ["src/index.ts", "src/serve.ts", "src/matrix.ts"], 5 | outDir: "dist", 6 | clean: true, 7 | format: ["esm"], 8 | minify: process.env.NODE_ENV !== "development", 9 | }) 10 | -------------------------------------------------------------------------------- /src/task/const.ts: -------------------------------------------------------------------------------- 1 | import path from "path" 2 | 3 | export const config_path = path.resolve("config") 4 | 5 | export const config_custom_path = path.join(config_path, "custom") 6 | 7 | export const m3u_path = path.resolve("m3u") 8 | 9 | export const write_custom_path = path.join(m3u_path, "custom") 10 | -------------------------------------------------------------------------------- /update-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 定时构建命令 4 | docker stop iptv-sources && docker rm iptv-sources && docker pull herberthe0229/iptv-sources:latest && docker run --name iptv-sources -p 3000:8080 -d herberthe0229/iptv-sources:latest 5 | 6 | # 获取历史版本 7 | UNUSED_IMAGES=$(docker images -q herberthe0229/iptv-sources --filter "dangling=true") 8 | 9 | # 删除历史版本 10 | if [ -n "$UNUSED_IMAGES" ]; 11 | then 12 | docker rmi $UNUSED_IMAGES 13 | fi 14 | -------------------------------------------------------------------------------- /src/utils/logo.ts: -------------------------------------------------------------------------------- 1 | import { channels_logo } from "./const" 2 | 3 | const is_fmml_logo_channel = (c: string) => channels_logo.includes(c) 4 | 5 | /** 6 | * @deprecated 计划建立自己的 logo 库,等待移除 7 | * @param c 8 | * @returns 9 | */ 10 | export const with_fmml_logo_channel = (c: string) => 11 | is_fmml_logo_channel(c) 12 | ? `https://live.fanmingming.com/tv/${c}.png` 13 | : is_fmml_logo_channel(c.toLowerCase()) 14 | ? `https://live.fanmingming.com/tv/${c.toLowerCase()}.png` 15 | : void 0 16 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/加入源镜像站-join-as-sources.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 加入源镜像站 Join as sources 3 | about: Join as sources for others 4 | title: "[\U0001F9D1‍\U0001F91D‍\U0001F9D1Join]" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **完善下面的信息 Complete the information** 11 | 12 | | 服务商 IDC | Http 协议(Protocol) | 源地址 URL | 自动更新频率 Auto-update frequence | 13 | | --- | --- | --- | --- | 14 | | ex. aliyun | http/https |ex. domain/ip:port | ex. 2h | 15 | 16 | - [ ] 同意每两个小时被检测可用性 Confirm to check usability per 2h 17 | - [ ] 已经配置 docker 上游镜像同步 Sync docker image from dockerhub 18 | - [ ] 源镜像站加入回滚计划 Join Rollback plan 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/问题反馈-bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 问题反馈 Bug report 3 | about: Create a report to help us improve 4 | title: "[\U0001F41BBUG]" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **描述问题 Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **如何复现 To Reproduce** 14 | Steps to reproduce the behavior. 15 | 16 | **期待结果 Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **截图 Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **其他补充 Additional context** 23 | Add any other context about the problem here. 24 | -------------------------------------------------------------------------------- /src/task/env/handler.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs" 2 | import path from "path" 3 | 4 | import { config_path } from "../const" 5 | import type { IEnv } from "./define" 6 | import { trimAny } from "../../utils" 7 | 8 | export const loadConfigEnv = (): IEnv | undefined => { 9 | if (!fs.existsSync(config_path)) { 10 | return void 0 11 | } 12 | 13 | if (fs.readdirSync(config_path).length === 0) { 14 | return void 0 15 | } 16 | 17 | const cfg = trimAny( 18 | JSON.parse( 19 | fs.readFileSync(path.join(config_path, "env.json"), "utf-8") 20 | ) as IEnv 21 | ) 22 | 23 | return cfg 24 | } 25 | -------------------------------------------------------------------------------- /.yarnclean: -------------------------------------------------------------------------------- 1 | # test directories 2 | __tests__ 3 | test 4 | tests 5 | powered-test 6 | 7 | # asset directories 8 | docs 9 | doc 10 | website 11 | images 12 | assets 13 | 14 | # examples 15 | example 16 | examples 17 | 18 | # code coverage directories 19 | coverage 20 | .nyc_output 21 | 22 | # build scripts 23 | Makefile 24 | Gulpfile.js 25 | Gruntfile.js 26 | 27 | # configs 28 | appveyor.yml 29 | circle.yml 30 | codeship-services.yml 31 | codeship-steps.yml 32 | wercker.yml 33 | .tern-project 34 | .gitattributes 35 | .editorconfig 36 | .*ignore 37 | .eslintrc 38 | .jshintrc 39 | .flowconfig 40 | .documentup.json 41 | .yarn-metadata.json 42 | .travis.yml 43 | 44 | # misc 45 | *.md 46 | -------------------------------------------------------------------------------- /src/task/custom/define.ts: -------------------------------------------------------------------------------- 1 | export interface ICustomRuleAppend { 2 | name: string 3 | url: string 4 | extinf?: string 5 | } 6 | 7 | export interface ICustomRuleReplacerItem { 8 | pattern: string 9 | type: "string" | "regexp" 10 | flags?: string 11 | target: string 12 | } 13 | 14 | export interface ICustomRuleReplacer { 15 | extinf?: ICustomRuleReplacerItem[] 16 | url?: ICustomRuleReplacerItem[] 17 | } 18 | 19 | export interface ICustomRule { 20 | upstream: string 21 | exclude?: string[] 22 | include?: string[] 23 | append?: ICustomRuleAppend[] 24 | replacer?: ICustomRuleReplacer 25 | } 26 | 27 | export interface ICustom { 28 | rules: ICustomRule[] 29 | } 30 | -------------------------------------------------------------------------------- /src/task/env/define.ts: -------------------------------------------------------------------------------- 1 | export interface IEnvSourcesProxyGitHubRawContent { 2 | close?: boolean 3 | custom?: string 4 | } 5 | 6 | export interface IEnvSourcesProxy { 7 | github_raw_content?: IEnvSourcesProxyGitHubRawContent 8 | } 9 | 10 | export interface IEnvSourcesRollback { 11 | urls?: string[] 12 | } 13 | 14 | export interface IEnvSources { 15 | rollback?: IEnvSourcesRollback 16 | proxy?: IEnvSourcesProxy 17 | } 18 | 19 | export interface IEnvExtendsIPTVChecker { 20 | enable?: boolean 21 | url?: string 22 | } 23 | 24 | export interface IEnvExtends { 25 | iptv_checker?: IEnvExtendsIPTVChecker 26 | } 27 | 28 | export interface IEnv { 29 | sources?: IEnvSources 30 | extends?: IEnvExtends 31 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/新的特性功能-feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 新的特性功能 Feature request 3 | about: Suggest an idea for this project 4 | title: "[✨Feat]" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **描述是否与问题相关 Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **描述你倾向的解决方案 Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **描述你考虑过的其他方案 Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **其他补充说明 Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/utils/id.ts: -------------------------------------------------------------------------------- 1 | import { converter } from "../sources/utils" 2 | 3 | export const get_channel_id = (extinf: string) => { 4 | const regExp = /\#EXTINF:-1([^,]*),(.*)/ 5 | const name = converter(regExp.exec(extinf)![2]).toLowerCase() 6 | 7 | return name 8 | .replace(/\[([^\]]*)\]/g, "") 9 | .replace(/\(([^\)]*)\)/g, "") 10 | .replace(/(([^)]*))/g, "") 11 | .replace(/「([^」]+)」/g, "") 12 | .replace(/\-/g, "") 13 | .replace(/\@\@[0-9]*/g, "") 14 | .replace(/Ⅰ/g, "") 15 | .replace(/ 8m/g, "") 16 | .replace(/([^\|]+)\|/g, "") 17 | .replace(/([^ⅰ]+)ⅰ/g, "") 18 | .replace(/([\u4e00-\u9fff]+)\s+([\u4e00-\u9fff]+)/g, "$1$2") 19 | .replace(/ +/g, " ") 20 | .trim() 21 | } 22 | -------------------------------------------------------------------------------- /src/sources/cymz6_lives.ts: -------------------------------------------------------------------------------- 1 | import { collectM3uSource } from "../utils" 2 | import { handle_m3u, ISource, type TSources } from "./utils" 3 | 4 | export const cymz6_lives_filter: ISource["filter"] = ( 5 | raw, 6 | caller, 7 | collectFn 8 | ): [string, number] => { 9 | const rawArray = handle_m3u(raw) 10 | 11 | if (caller === "normal" && collectFn) { 12 | for (let i = 1; i < rawArray.length; i += 2) { 13 | collectM3uSource(rawArray[i], rawArray[i + 1], collectFn) 14 | } 15 | } 16 | 17 | return [rawArray.join("\n"), (rawArray.length - 1) / 2] 18 | } 19 | 20 | export const cymz6_lives_sources: TSources = [ 21 | { 22 | name: "cymz6/AutoIPTV-Hotel lives", 23 | f_name: "cymz6_lives", 24 | url: "https://raw.githubusercontent.com/cymz6/AutoIPTV-Hotel/main/lives.m3u", 25 | filter: cymz6_lives_filter, 26 | }, 27 | ] 28 | -------------------------------------------------------------------------------- /src/checker/caniuse.ts: -------------------------------------------------------------------------------- 1 | import path from "path" 2 | import fs from "fs" 3 | 4 | import "dotenv/config" 5 | 6 | /** 7 | * 检查文件是否可用 8 | * @param f 9 | * @returns 10 | */ 11 | export const canIUseM3uFile = (f: string) => { 12 | const m3u_p = path.resolve("m3u", f) 13 | return fs.existsSync(m3u_p) 14 | } 15 | 16 | /** 17 | * 检查 iptv-checker 环境 18 | * @returns 19 | */ 20 | export const canIUseIPTVChecker = async () => { 21 | const { ENABLE_IPTV_CHECKER, IPTV_CHECKER_URL } = process.env 22 | 23 | if (ENABLE_IPTV_CHECKER !== "true" || !IPTV_CHECKER_URL) return false 24 | 25 | try { 26 | const res = await fetch(IPTV_CHECKER_URL) 27 | if (/^[2]/.test(res.status.toString())) { 28 | return true 29 | } else { 30 | return false 31 | } 32 | } catch (err) { 33 | return false 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/epgs/index.ts: -------------------------------------------------------------------------------- 1 | import { with_github_raw_url_proxy } from "../sources" 2 | import type { TEPGSource } from "./utils" 3 | 4 | export const epgs_sources: TEPGSource[] = [ 5 | { 6 | name: "112114.xyz", 7 | f_name: "112114_xyz", 8 | url: "https://epg.112114.xyz/pp.xml", 9 | }, 10 | { 11 | name: "fanmingming/live", 12 | f_name: "fmml", 13 | url: "https://raw.githubusercontent.com/fanmingming/live/main/e.xml", 14 | }, 15 | { 16 | name: "51zmt.top", 17 | f_name: "51zmt", 18 | url: "http://epg.51zmt.top:8000/e.xml", 19 | }, 20 | { 21 | name: "51zmt.top cc", 22 | f_name: "51zmt_cc", 23 | url: "http://epg.51zmt.top:8000/cc.xml", 24 | }, 25 | { 26 | name: "51zmt.top difang", 27 | f_name: "51zmt_df", 28 | url: "http://epg.51zmt.top:8000/difang.xml", 29 | }, 30 | ] 31 | -------------------------------------------------------------------------------- /src/utils/trim.ts: -------------------------------------------------------------------------------- 1 | export const trimAny = (any: any) => { 2 | if (Array.isArray(any)) { 3 | return any.map((a: any) => { 4 | if (typeof a === "string") { 5 | return a.trim() 6 | } 7 | 8 | if (typeof a === "object") { 9 | return trimAny(a) 10 | } 11 | }) 12 | } 13 | 14 | if (typeof any === "object") { 15 | return Object.fromEntries( 16 | Object.entries(any).map(([key, value]) => { 17 | if (typeof value === "string") { 18 | return [key, value.trim()] 19 | } 20 | 21 | if (typeof value === "object") { 22 | return [key, trimAny(value)] 23 | } 24 | }) 25 | ) 26 | } 27 | 28 | if (typeof any === "string") { 29 | return any.trim() 30 | } 31 | 32 | return any 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: docker image 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | buildx: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v4 13 | - # Add support for more platforms with QEMU (optional) 14 | # https://github.com/docker/setup-qemu-action 15 | name: Set up QEMU 16 | uses: docker/setup-qemu-action@v3 17 | - name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v3 19 | - name: Login to DockerHub 20 | uses: docker/login-action@v2 21 | with: 22 | username: ${{ secrets.DOCKERHUB_USERNAME }} 23 | password: ${{ secrets.DOCKERHUB_TOKEN }} 24 | - name: Build image 25 | run: | 26 | docker buildx build -t herberthe0229/iptv-sources:latest --platform=linux/arm64,linux/amd64,linux/arm/v8,linux/arm/v7 . --push 27 | 28 | -------------------------------------------------------------------------------- /src/sources/yuechan_live.ts: -------------------------------------------------------------------------------- 1 | import { replace_github_raw_proxy_url, collectM3uSource } from "../utils" 2 | import { handle_m3u, ISource, type TSources } from "./utils" 3 | 4 | export const yuechan_live_filter: ISource["filter"] = ( 5 | raw, 6 | caller, 7 | collectFn 8 | ): [string, number] => { 9 | const rawArray = handle_m3u(replace_github_raw_proxy_url(raw)) 10 | 11 | if (caller === "normal" && collectFn) { 12 | for (let i = 1; i < rawArray.length; i += 2) { 13 | collectM3uSource(rawArray[i], rawArray[i + 1], collectFn) 14 | } 15 | } 16 | 17 | return [rawArray.join("\n"), (rawArray.length - 1) / 2] 18 | } 19 | 20 | export const yuechan_live_sources: TSources = [ 21 | { 22 | name: "YueChan-Live IPTV", 23 | f_name: "ycl_iptv", 24 | url: "https://raw.githubusercontent.com/YueChan/Live/main/IPTV.m3u", 25 | filter: yuechan_live_filter, 26 | }, 27 | ] 28 | -------------------------------------------------------------------------------- /src/sources/yang_m3u.ts: -------------------------------------------------------------------------------- 1 | import { replace_github_raw_proxy_url, collectM3uSource } from "../utils" 2 | import { handle_m3u, type TSources, converter, ISource } from "./utils" 3 | 4 | export const yang_m3u_filter: ISource["filter"] = ( 5 | raw, 6 | caller, 7 | collectFn 8 | ): [string, number] => { 9 | const rawArray = handle_m3u(replace_github_raw_proxy_url(raw)) 10 | 11 | if (caller === "normal" && collectFn) { 12 | for (let i = 1; i < rawArray.length; i += 2) { 13 | collectM3uSource(rawArray[i], rawArray[i + 1], collectFn) 14 | } 15 | } 16 | 17 | return [converter(rawArray.join("\n")), (rawArray.length - 1) / 2] 18 | } 19 | 20 | export const yang_m3u_sources: TSources = [ 21 | { 22 | name: "YanG-1989 Gather", 23 | f_name: "y_g", 24 | url: "https://raw.githubusercontent.com/YanG-1989/m3u/main/Gather.m3u", 25 | filter: yang_m3u_filter, 26 | }, 27 | ] 28 | -------------------------------------------------------------------------------- /src/sources/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./epg_pw" 2 | export * from "./iptv_org" 3 | export * from "./yang_m3u" 4 | export * from "./yuechan_live" 5 | export * from "./fanmingming_live" 6 | export * from "./qwerttvv_bj_iptv" 7 | export * from "./joevess_iptv" 8 | export * from "./cymz6_lives" 9 | export * from "./utils" 10 | 11 | import { 12 | epg_pw_sources, 13 | iptv_org_sources, 14 | iptv_org_stream_sources, 15 | yang_m3u_sources, 16 | yuechan_live_sources, 17 | fanmingming_live_sources, 18 | qwerttvv_bj_iptv_sources, 19 | joevess_iptv_sources, 20 | cymz6_lives_sources 21 | } from "." 22 | 23 | export const sources = [ 24 | ...fanmingming_live_sources, 25 | ...yuechan_live_sources, 26 | ...cymz6_lives_sources, 27 | ...yang_m3u_sources, 28 | ...joevess_iptv_sources, 29 | ...iptv_org_sources, 30 | ...iptv_org_stream_sources, 31 | ...epg_pw_sources, 32 | ...qwerttvv_bj_iptv_sources, 33 | ] 34 | -------------------------------------------------------------------------------- /scripts/release.js: -------------------------------------------------------------------------------- 1 | import readline from "readline/promises" 2 | import fs from "fs" 3 | import path from "path" 4 | import { execSync } from "child_process" 5 | 6 | const rl = readline.createInterface({ 7 | input: process.stdin, 8 | output: process.stdout, 9 | }) 10 | 11 | const updatePackageJson = (version) => { 12 | const fp = path.resolve("package.json") 13 | const content = fs.readFileSync(fp, "utf-8") 14 | fs.writeFileSync( 15 | fp, 16 | content.replace(/"version": ".*"/, `"version": "${version}"`), 17 | "utf-8" 18 | ) 19 | } 20 | 21 | const commitVersion = (version) => { 22 | execSync("git add .") 23 | execSync(`git commit -m :bookmark:v${version}`) 24 | } 25 | 26 | rl.question("input the release version? ex: 1.0.0\n") 27 | .then((version) => { 28 | if (!version) { 29 | console.error("[ERROR] Invalid version") 30 | return 31 | } 32 | const ver = version.trim() 33 | 34 | updatePackageJson(ver) 35 | commitVersion(ver) 36 | }) 37 | .finally(() => { 38 | rl.close() 39 | }) 40 | -------------------------------------------------------------------------------- /src/sources/joevess_iptv.ts: -------------------------------------------------------------------------------- 1 | import { collectM3uSource } from "../utils" 2 | import { handle_m3u, ISource, type TSources } from "./utils" 3 | 4 | export const joevess_iptv_filter: ISource["filter"] = ( 5 | raw, 6 | caller, 7 | collectFn 8 | ): [string, number] => { 9 | const rawArray = handle_m3u(raw) 10 | 11 | if (!/#EXTM3U/.test(rawArray[0])) { 12 | rawArray.unshift("#EXTM3U") 13 | } 14 | 15 | if (caller === "normal" && collectFn) { 16 | for (let i = 1; i < rawArray.length; i += 2) { 17 | collectM3uSource(rawArray[i], rawArray[i + 1], collectFn) 18 | } 19 | } 20 | 21 | return [rawArray.join("\n"), (rawArray.length - 1) / 2] 22 | } 23 | 24 | export const joevess_iptv_sources: TSources = [ 25 | { 26 | name: "joevess/IPTV home", 27 | f_name: "j_home", 28 | url: "https://raw.githubusercontent.com/joevess/IPTV/main/home.m3u8", 29 | filter: joevess_iptv_filter, 30 | }, 31 | { 32 | name: "joevess/IPTV iptv", 33 | f_name: "j_iptv", 34 | url: "https://raw.githubusercontent.com/joevess/IPTV/main/iptv.m3u8", 35 | filter: joevess_iptv_filter, 36 | }, 37 | ] 38 | -------------------------------------------------------------------------------- /src/utils/m3u2txt.ts: -------------------------------------------------------------------------------- 1 | export const m3u2txt = (m3uArray: string[]) => { 2 | let groups = new Map() 3 | const channelRegExp = /\#EXTINF:-1([^,]*),(.*)/ 4 | const groupRegExp = /group-title="([^"]*)"/ 5 | 6 | for (let i = 1; i < m3uArray.length; i += 2) { 7 | const reg = channelRegExp.exec(m3uArray[i]) as RegExpExecArray 8 | const group = groupRegExp.exec(reg[1].trim()) 9 | let g = "" 10 | 11 | if (!group) { 12 | g = "Undefined" 13 | } else { 14 | g = group[1].trim() 15 | } 16 | 17 | if (groups.has(g)) { 18 | groups.set( 19 | g, 20 | `${groups.get(g)}${reg[2].trim().replace(/\s+/g, "_")},${ 21 | m3uArray[i + 1] 22 | }\n` 23 | ) 24 | } else { 25 | groups.set( 26 | g, 27 | `${reg[2].trim().replace(/\s+/g, "_")},${m3uArray[i + 1]}\n` 28 | ) 29 | } 30 | } 31 | 32 | let txt = "" 33 | 34 | groups.forEach((v, k) => { 35 | txt += `${k},#genre#\n${v}\n` 36 | }) 37 | 38 | return txt.substring(0, txt.length - 2) 39 | } 40 | -------------------------------------------------------------------------------- /src/utils/collector.ts: -------------------------------------------------------------------------------- 1 | import { get_channel_id } from "./id" 2 | 3 | export const Collector = ( 4 | keyFilter?: (k: string) => boolean, 5 | valueFilter?: (v: string) => boolean 6 | ) => { 7 | let data = new Map() 8 | 9 | return { 10 | collect: (k: string, v: string) => { 11 | if (!!keyFilter && keyFilter(k)) { 12 | return 13 | } 14 | 15 | if (!!valueFilter && valueFilter(v)) { 16 | return 17 | } 18 | 19 | if (data.has(k)) { 20 | const vb = data.get(k) 21 | if (!vb) { 22 | data.set(k, [v]) 23 | return 24 | } 25 | 26 | if (!vb.includes(v)) { 27 | data.set(k, [...vb, v]) 28 | return 29 | } 30 | } else { 31 | data.set(k, [v]) 32 | } 33 | }, 34 | result: () => { 35 | return data 36 | }, 37 | } 38 | } 39 | 40 | export const collectM3uSource = ( 41 | extinf: string, 42 | url: string, 43 | fn: (k: string, v: string) => void 44 | ) => { 45 | const id = get_channel_id(extinf) 46 | fn(id, url) 47 | } 48 | -------------------------------------------------------------------------------- /src/sources/fanmingming_live.ts: -------------------------------------------------------------------------------- 1 | import { collectM3uSource } from "../utils" 2 | import { handle_m3u, ISource, type TSources } from "./utils" 3 | 4 | export const fanmingming_live_filter: ISource["filter"] = ( 5 | raw, 6 | caller, 7 | collectFn 8 | ): [string, number] => { 9 | const rawArray = handle_m3u(raw) 10 | 11 | if (caller === "normal" && collectFn) { 12 | for (let i = 1; i < rawArray.length; i += 2) { 13 | collectM3uSource(rawArray[i], rawArray[i + 1], collectFn) 14 | } 15 | } 16 | 17 | return [rawArray.join("\n"), (rawArray.length - 1) / 2] 18 | } 19 | 20 | export const fanmingming_live_sources: TSources = [ 21 | { 22 | name: "fanmingming/live ipv6", 23 | f_name: "fmml_ipv6", 24 | url: "https://raw.githubusercontent.com/fanmingming/live/main/tv/m3u/ipv6.m3u", 25 | filter: fanmingming_live_filter, 26 | }, 27 | { 28 | name: "fanmingming/live itv", 29 | f_name: "fmml_itv", 30 | url: "https://raw.githubusercontent.com/fanmingming/live/main/tv/m3u/itv.m3u", 31 | filter: fanmingming_live_filter, 32 | }, 33 | { 34 | name: "fanmingming/live index", 35 | f_name: "fmml_index", 36 | url: "https://raw.githubusercontent.com/fanmingming/live/main/tv/m3u/index.m3u", 37 | filter: fanmingming_live_filter, 38 | }, 39 | ] 40 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: update script 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | matrix: 13 | node-version: [20.x] 14 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | cache: "npm" 24 | - name: install yarn 25 | run: npm install yarn -g 26 | - run: yarn install 27 | - run: yarn build 28 | - run: yarn m3u 29 | - run: yarn matrix 30 | 31 | - name: "Jekyll theme" 32 | run: mv ./_config.temp.yml ./m3u/_config.yml 33 | 34 | - name: Deploy 35 | uses: peaceiris/actions-gh-pages@v3 36 | with: 37 | github_token: ${{ secrets.GITHUB_TOKEN }} 38 | publish_dir: ./m3u 39 | enable_jekyll: true 40 | cname: m3u.ibert.me 41 | 42 | - name: discord 43 | uses: HerbertHe/discord-action@v1 44 | with: 45 | webhook: ${{ secrets.DISCORD_WEBHOOK }} 46 | message: ${{ github.repository }} has been successfullly updated, see https://m3u.ibert.me to get more. 47 | -------------------------------------------------------------------------------- /.github/workflows/schedule.yml: -------------------------------------------------------------------------------- 1 | name: update schedule 2 | 3 | on: 4 | schedule: 5 | - cron: "0 */2 * * *" 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | matrix: 13 | node-version: [20.x] 14 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | cache: "npm" 24 | - name: install yarn 25 | run: npm install yarn -g 26 | - run: yarn install 27 | - run: yarn build 28 | - run: yarn m3u 29 | - run: yarn matrix 30 | 31 | - name: "Jekyll theme" 32 | run: mv ./_config.temp.yml ./m3u/_config.yml 33 | 34 | - name: Deploy 35 | uses: peaceiris/actions-gh-pages@v3 36 | with: 37 | github_token: ${{ secrets.GITHUB_TOKEN }} 38 | publish_dir: ./m3u 39 | enable_jekyll: true 40 | cname: m3u.ibert.me 41 | 42 | - name: discord 43 | uses: HerbertHe/discord-action@v1 44 | with: 45 | webhook: ${{ secrets.DISCORD_WEBHOOK }} 46 | message: ${{ github.repository }} has been successfullly updated, see https://m3u.ibert.me to get more. 47 | -------------------------------------------------------------------------------- /README.temp.md: -------------------------------------------------------------------------------- 1 | # iptv-sources 2 | 3 | Autoupdate iptv sources 4 | 5 | GitHub: [HerbertHe/iptv-sources](https://github.com/HerbertHe/iptv-sources) 6 | 7 | Join discord: [![Discord](https://discord.badge.ibert.me/api/server/betxHcsTqa)](https://discord.gg/betxHcsTqa) 8 | 9 | Sources are from: 10 | 11 | - 12 | - [iptv.org](https://github.com/iptv-org/iptv) 13 | - [YueChan/Live](https://github.com/YueChan/Live) 14 | - [YanG-1989/m3u](https://github.com/YanG-1989/m3u) 15 | - [fanmingming/live](https://github.com/fanmingming/live) 16 | - [qwerttvv/Beijing-IPTV](https://github.com/qwerttvv/Beijing-IPTV) 17 | - [joevess/IPTV](https://github.com/joevess/IPTV) 18 | - [cymz6/AutoIPTV-Hotel](https://github.com/cymz6/AutoIPTV-Hotel) 19 | 20 | EPG Sources are from: 21 | 22 | - [fanmingming/live](https://github.com/fanmingming/live) 23 | - [112114.xyz](https://diyp1.112114.xyz) 24 | - [epg.51zmt.top:8000](http://epg.51zmt.top:8000/) 25 | 26 | ## Matrix 27 | 28 | You can also use the services provided by Mirror Sites Matrix! See for more. 29 | 30 | 31 | ## Channel 32 | 33 | | channel | url | list | count | isRollback | 34 | | ------- | --- | ---- | ----- | ---------- | 35 | 36 | 37 | ## EPG 38 | 39 | | epg | url | isRollback | 40 | | --- | --- | ---------- | 41 | 42 | 43 | See to get more. 44 | 45 | ## LICENSE 46 | 47 | GPL-3.0 © Herbert He 48 | 49 | 本项目基于 GPL-3.0 协议开源。 50 | -------------------------------------------------------------------------------- /src/sources/utils.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config" 2 | 3 | import * as OpenCC from "opencc-js" 4 | import { get_github_raw_proxy_url } from "../utils" 5 | 6 | export interface ISource { 7 | name: string 8 | f_name: string 9 | url: string 10 | filter: ( 11 | raw: string, 12 | caller: "normal" | "skip" | "rollback", 13 | collectFn?: (k: string, v: string) => void 14 | ) => [string, number] 15 | } 16 | 17 | export type TSources = ISource[] 18 | 19 | export const converter = OpenCC.Converter({ from: "hk", to: "cn" }) 20 | 21 | export const handle_m3u = (r: string) => { 22 | const raw = r 23 | .trim() 24 | .replace(/\r/g, "") 25 | .split("\n") 26 | .filter((r) => !!r) 27 | 28 | let result: string[] = [] 29 | 30 | const extM3uRegExp = /#EXTM3U/ 31 | const extinfRegExp = /#EXTINF:-1([^,]*),(.*)/ 32 | const hostRegExp = /^([^:]+):\/\/([^/]+)/ 33 | 34 | for (let i = 0; i < raw.length; i++) { 35 | if (extM3uRegExp.test(raw[i])) { 36 | result.push(raw[i]) 37 | continue 38 | } 39 | 40 | if (extinfRegExp.test(raw[i]) && hostRegExp.test(raw[i + 1])) { 41 | result = result.concat([raw[i], raw[i + 1]]) 42 | i++ 43 | continue 44 | } 45 | } 46 | 47 | return result 48 | } 49 | 50 | export const with_github_raw_url_proxy = (u: string) => { 51 | return process.env.CLOSE_SOURCE_PROXY?.trim() === "true" 52 | ? u 53 | : `${get_github_raw_proxy_url()}/${u}` 54 | } 55 | -------------------------------------------------------------------------------- /src/tvbox/utils.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs" 2 | import path from "path" 3 | 4 | import { get_custom_url } from "../utils" 5 | 6 | interface ITvBoxLiveChannel { 7 | name: string 8 | urls: string[] 9 | } 10 | 11 | interface ITvBoxLive { 12 | group: string 13 | channels: ITvBoxLiveChannel[] 14 | } 15 | 16 | interface ITvBoxJson { 17 | lives: ITvBoxLive[] 18 | } 19 | 20 | interface ITvBoxLiveSrc { 21 | name: string 22 | f_name: string 23 | } 24 | 25 | const gen_tvbox_json = (srcs: ITvBoxLiveSrc[], group?: string): ITvBoxJson => { 26 | if (srcs.length < 1) { 27 | throw new Error("No sources for tvbox found!") 28 | } 29 | 30 | const j = { 31 | lives: [], 32 | } as ITvBoxJson 33 | 34 | const live = { 35 | group: !!group ? group : srcs[0].name, 36 | channels: srcs.map( 37 | ({ name, f_name }) => 38 | ({ 39 | name, 40 | urls: [`${get_custom_url()}/txt/${f_name}.txt`], 41 | } as ITvBoxLiveChannel) 42 | ), 43 | } as ITvBoxLive 44 | 45 | j.lives.push(live) 46 | 47 | return j 48 | } 49 | 50 | export const writeTvBoxJson = ( 51 | f_name: string, 52 | srcs: ITvBoxLiveSrc[], 53 | group?: string 54 | ) => { 55 | const tvbox_p = path.resolve("m3u", "tvbox") 56 | if (!fs.existsSync(tvbox_p)) { 57 | fs.mkdirSync(tvbox_p) 58 | } 59 | 60 | fs.writeFileSync( 61 | path.join(tvbox_p, `${f_name}.json`), 62 | JSON.stringify(gen_tvbox_json(srcs, group)) 63 | ) 64 | } 65 | -------------------------------------------------------------------------------- /src/channels.ts: -------------------------------------------------------------------------------- 1 | import path from "path" 2 | import fs from "fs" 3 | 4 | import { get_custom_url } from "./utils" 5 | 6 | export interface IChannelSource { 7 | name: string 8 | f_name: string 9 | } 10 | 11 | export type TChannelsSources = IChannelSource[] 12 | 13 | export type TChannelEpgs = TChannelsSources 14 | 15 | export interface IChannel { 16 | name: string 17 | m3u: string 18 | count: number | undefined 19 | } 20 | 21 | export interface IEPG { 22 | name: string 23 | epg: string 24 | } 25 | 26 | export interface IChannelsResult { 27 | builderVersion?: number // 构建版本标识符 28 | channels: IChannel[] 29 | epgs: IEPG[] 30 | updated_at: number 31 | } 32 | 33 | export const updateChannelsJson = ( 34 | sources: TChannelsSources, 35 | sources_res: Array<[string, number | undefined]>, 36 | epgs: TChannelEpgs 37 | ) => { 38 | const json_p = path.resolve("m3u", "channels.json") 39 | const url = get_custom_url() 40 | 41 | const result: IChannelsResult = { 42 | builderVersion: 1, 43 | channels: sources?.map((source, idx) => ({ 44 | name: source.name, 45 | m3u: `${url}/${source.f_name}.m3u`, 46 | count: sources_res?.[idx]?.[1], 47 | })), 48 | epgs: epgs?.map((epg) => ({ 49 | name: epg.name, 50 | epg: `${url}/epg/${epg.f_name}.xml`, 51 | })), 52 | updated_at: new Date().getTime(), 53 | } 54 | 55 | if (!fs.existsSync(path.resolve("m3u"))) { 56 | fs.mkdirSync(path.resolve("m3u")) 57 | } 58 | 59 | fs.writeFileSync(json_p, JSON.stringify(result)) 60 | } 61 | -------------------------------------------------------------------------------- /src/sources/qwerttvv_bj_iptv.ts: -------------------------------------------------------------------------------- 1 | import { collectM3uSource } from "../utils" 2 | import { handle_m3u, ISource, type TSources } from "./utils" 3 | 4 | export const qwerttvv_bj_iptv_filter: ISource["filter"] = ( 5 | raw, 6 | caller, 7 | collectFn 8 | ): [string, number] => { 9 | const rawArray = handle_m3u(raw) 10 | 11 | let result = rawArray.filter((r) => !/^#\s+/.test(r)) 12 | 13 | if (caller === "normal" && collectFn) { 14 | for (let i = 1; i < result.length; i += 2) { 15 | collectM3uSource(result[i], result[i + 1], collectFn) 16 | } 17 | } 18 | 19 | return [result.join("\n"), (result.length - 1) / 2] 20 | } 21 | 22 | export const qwerttvv_bj_iptv_sources: TSources = [ 23 | { 24 | name: "qwerttvv/Beijing-IPTV IPTV Unicom", 25 | f_name: "q_bj_iptv_unicom", 26 | url: "https://raw.githubusercontent.com/qwerttvv/Beijing-IPTV/master/IPTV-Unicom.m3u", 27 | filter: qwerttvv_bj_iptv_filter, 28 | }, 29 | { 30 | name: "qwerttvv/Beijing-IPTV IPTV Unicom Multicast", 31 | f_name: "q_bj_iptv_unicom_m", 32 | url: "https://raw.githubusercontent.com/qwerttvv/Beijing-IPTV/master/IPTV-Unicom-Multicast.m3u", 33 | filter: qwerttvv_bj_iptv_filter, 34 | }, 35 | { 36 | name: "qwerttvv/Beijing-IPTV IPTV Mobile", 37 | f_name: "q_bj_iptv_mobile", 38 | url: "https://raw.githubusercontent.com/qwerttvv/Beijing-IPTV/master/IPTV-Mobile.m3u", 39 | filter: qwerttvv_bj_iptv_filter, 40 | }, 41 | { 42 | name: "qwerttvv/Beijing-IPTV IPTV Mobile Multicast", 43 | f_name: "q_bj_iptv_mobile_m", 44 | url: "https://raw.githubusercontent.com/qwerttvv/Beijing-IPTV/master/IPTV-Mobile-Multicast.m3u", 45 | filter: qwerttvv_bj_iptv_filter, 46 | }, 47 | ] 48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iptv-sources", 3 | "version": "1.6.6", 4 | "main": "index.js", 5 | "repository": "git@github.com:HerbertHe/iptv-sources.git", 6 | "author": "HerbertHe ", 7 | "type": "module", 8 | "license": "GPL-3.0-only", 9 | "scripts": { 10 | "dev": "cross-env NODE_ENV=development tsup --watch", 11 | "build": "tsup", 12 | "m3u": "node ./dist/index.js", 13 | "serve": "node ./dist/serve.js", 14 | "serve:dev": "nodemon ./dist/serve.js", 15 | "matrix": "node ./dist/matrix.js", 16 | "release": "node ./scripts/release.js", 17 | "docker:build": "docker buildx build -t herberthe0229/iptv-sources:latest --platform=linux/arm64,linux/amd64,linux/arm/v8,linux/arm/v7 . --push", 18 | "docker:build:dev": "docker buildx build -t herberthe0229/iptv-sources:dev --platform=linux/arm64,linux/amd64,linux/arm/v8,linux/arm/v7 . --push", 19 | "docker:build:local": "docker buildx build -t herberthe0229/iptv-sources:dev --platform=linux/arm64,linux/amd64,linux/arm/v8,linux/arm/v7 .", 20 | "push": "yarn release && git push && yarn docker:build" 21 | }, 22 | "devDependencies": { 23 | "@rollup/wasm-node": "4.20.0", 24 | "@types/koa": "^2.15.0", 25 | "@types/koa-router": "^7.4.8", 26 | "@types/koa-static": "4.0.4", 27 | "@types/markdown-it": "14.1.2", 28 | "@types/node": "22.2.0", 29 | "@types/opencc-js": "1.0.3", 30 | "cross-env": "^7.0.3", 31 | "nodemon": "^3.1.4", 32 | "tsup": "8.2.4", 33 | "typescript": "5.5.4" 34 | }, 35 | "dependencies": { 36 | "dotenv": "^16.4.5", 37 | "koa": "2.15.3", 38 | "koa-router": "12.0.1", 39 | "koa-static": "5.0.0", 40 | "markdown-it": "14.1.0", 41 | "opencc-js": "1.0.5" 42 | }, 43 | "resolutions": { 44 | "rollup": "npm:@rollup/wasm-node" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/matrix.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs" 2 | import path from "path" 3 | 4 | import type { IChannelsResult } from "./channels" 5 | 6 | import { sites_matrix } from "./utils" 7 | 8 | // 仅支持 GitHub Action 进行镜像站测试,降低镜像站负载压力 9 | 10 | const matrixGen = ( 11 | m: string 12 | ) => `| HTTP Protocol | URL | Auto-update Frequence | Latest Updated | IDC | Provider | 13 | | ------------- | --- | --------------------- | --- | --- | -------- | 14 | ${m} 15 | ` 16 | 17 | const requestMirrorSite = (url: string): Promise => { 18 | return new Promise(async (resolve, reject) => { 19 | try { 20 | const res = await fetch(`${url}/channels.json`) 21 | if (/^[2]/.test(res.status.toString())) { 22 | const channles = JSON.parse(await res.text()) as IChannelsResult 23 | resolve(new Date(channles.updated_at).toString()) 24 | } else { 25 | reject(`Get Updated Failed: **${res.statusText}**`) 26 | } 27 | } catch (err) { 28 | reject(`Get Updated Failed: **${err.toString()}**`) 29 | } 30 | }) 31 | } 32 | 33 | const updateMatrix = async () => { 34 | const readme_p = path.resolve("m3u", "README.md") 35 | 36 | const m = await Promise.allSettled( 37 | sites_matrix?.map(async (m) => { 38 | let test = "" 39 | try { 40 | test = await requestMirrorSite(m.url) 41 | } catch (err) { 42 | test = err 43 | } finally { 44 | return `| ${m.protocol} | <${m.url}> | ${m.frequence} | ${test} | ${m.idc} | ${m.provider} |` 45 | } 46 | }) 47 | ) 48 | 49 | const back = matrixGen( 50 | (m) 51 | .map((mm) => { 52 | return mm.value 53 | }) 54 | .join("\n") 55 | ) 56 | 57 | const readme = fs.readFileSync(readme_p, "utf8").toString() 58 | fs.writeFileSync(readme_p, readme.replace("", back)) 59 | } 60 | 61 | updateMatrix() 62 | -------------------------------------------------------------------------------- /src/utils/from.ts: -------------------------------------------------------------------------------- 1 | const from_infos = new Map([ 2 | ["sn.chinamobile.com", "中国移动陕西"], 3 | ["sh.chinamobile.com", "中国移动上海"], 4 | ["hl.chinamobile.com", "中国移动黑龙江"], 5 | ["js.chinamobile.com", "中国移动江苏"], 6 | ["cztv.com", "浙江广播电视集团"], 7 | ["mobaibox.com", "中国移动江苏"], 8 | ["shaoxing.com.cn", "绍兴网"], 9 | ["cztvcloud.com", "新蓝云"], 10 | ["btzx.com.cn", "兵团在线网站"], 11 | ["hznet.tv", "菏泽网络电视台"], 12 | ["xntv.tv", "西宁网络电视台"], 13 | ["jlntv.cn", "吉林广播电视台"], 14 | ["ybtvyun.com", "延边广播电视台"], 15 | ["dxhmt.cn", "河南大象融媒体"], 16 | ["hebyun.com.cn", "冀云"], 17 | ["nntv.cn", "老友网"], 18 | ["sjzntv.cn", "燕赵名城网"], 19 | ["yjtvw.com", "阳江广播电视台"], 20 | ["amazonaws.com", "亚马逊AWS"], 21 | ["jstv.com", "荔枝网"], 22 | ["sgmsw.cn", "韶关民声网"], 23 | ["grtn.cn", "广东网络广播电视台"], 24 | ["nbs.cn", "南京广播电视台"], 25 | ["lsrmw.cn", "溧水融媒网"], 26 | ["zohi.tv", "福州明珠"], 27 | ["qingting.fm", "蜻蜓FM"], 28 | ["hhtv.cc", "云南红河发布"], 29 | ["wsrtv.com.cn", "文山州广播电视台"], 30 | ["xsbnrtv.cn", "西双版纳广播电视网"], 31 | ["live.yantaitv.cn", "烟台网络广播电视台"], 32 | ["cgtn.com", "CGTN"], 33 | ["cctv.com", "CCTV"], 34 | ["cctvplus.com", "CCTV+"], 35 | ["cnr.cn", "央广网"], 36 | ["cmvideo.cn", "咪咕"], 37 | ["douyucdn", "斗鱼"], 38 | ["cri.cn", "国际在线"], 39 | ["hndt.com", "河南广播网"], 40 | ["qxndt.com", "黔西南广播网"], 41 | ["olelive.com", "欧乐影院"], 42 | ["chinashadt.com", "千城云科"], 43 | ["aodianyun.com", "奥点云"], 44 | ["xiancity.cn", "西安网"], 45 | ["raw.githubusercontent.com", "Github Raw"], 46 | ]) 47 | 48 | export const get_from_info = (url: string) => { 49 | for (const [k, v] of from_infos) { 50 | if (url.includes(k)) { 51 | return v 52 | } 53 | } 54 | 55 | const hostRegExp = /([^:]+):\/\/([^/]+)/ 56 | 57 | const host = hostRegExp.exec(url)![2] 58 | 59 | if (/^\[/.test(host)) { 60 | return "IPv6 直链" 61 | } 62 | 63 | if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:\d+)?$/.test(host)) { 64 | return "IPv4 直链" 65 | } 66 | 67 | return host 68 | } 69 | -------------------------------------------------------------------------------- /src/sources/epg_pw.ts: -------------------------------------------------------------------------------- 1 | import { collectM3uSource } from "../utils" 2 | import { converter, handle_m3u } from "./utils" 3 | import type { ISource, TSources } from "./utils" 4 | 5 | export const epg_pw_filter: ISource["filter"] = ( 6 | raw, 7 | caller, 8 | collectFn 9 | ): [string, number] => { 10 | const rawArray = handle_m3u(raw) 11 | const regExp = /\#EXTINF:-1\s+tvg\-name\=\"([^"]+)\"/ 12 | 13 | let i = 1 14 | let sourced: string[] = [] 15 | let result = [rawArray[0]] 16 | 17 | while (i < rawArray.length) { 18 | const reg = regExp.exec(rawArray[i]) as RegExpExecArray 19 | 20 | if (!!reg) { 21 | if (caller === "normal" && collectFn) { 22 | collectM3uSource(rawArray[i], rawArray[i + 1], collectFn) 23 | } 24 | 25 | if (!sourced.includes(reg[1])) { 26 | sourced.push(reg[1]) 27 | result.push( 28 | rawArray[i] 29 | .replace(/\@\@[0-9]*/g, "") 30 | .replace(/\[geo\-blocked\]/, "") 31 | .replace(/\[Geo\-blocked\]/, "") 32 | .trim() 33 | ) 34 | result.push(rawArray[i + 1]) 35 | } 36 | } 37 | 38 | i += 2 39 | } 40 | 41 | return [converter(result.join("\n")), (result.length - 1) / 2] 42 | } 43 | 44 | export const epg_pw_sources: TSources = [ 45 | { 46 | name: "epg.pw China", 47 | f_name: "cn", 48 | url: "https://epg.pw/test_channels_china.m3u", 49 | filter: epg_pw_filter, 50 | }, 51 | { 52 | name: "epg.pw China National", 53 | f_name: "cn_n", 54 | url: "https://epg.pw/test_channels_china_national.m3u", 55 | filter: epg_pw_filter, 56 | }, 57 | { 58 | name: "epg.pw China Country", 59 | f_name: "cn_c", 60 | url: "https://epg.pw/test_channels_china_country.m3u", 61 | filter: epg_pw_filter, 62 | }, 63 | { 64 | name: "epg.pw China Province", 65 | f_name: "cn_p", 66 | url: "https://epg.pw/test_channels_china_province.m3u", 67 | filter: epg_pw_filter, 68 | }, 69 | { 70 | name: "epg.pw All", 71 | f_name: "all", 72 | url: "https://epg.pw/test_channels_all.m3u", 73 | filter: epg_pw_filter, 74 | }, 75 | ] 76 | -------------------------------------------------------------------------------- /src/utils/handlers.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config" 2 | 3 | interface IREADMEMirrorSite { 4 | protocol: "http" | "https" 5 | url: string 6 | frequence: string 7 | idc: string 8 | provider: string 9 | } 10 | 11 | type TREADMEMirrorSitesMatrix = IREADMEMirrorSite[] 12 | 13 | export const sites_matrix: TREADMEMirrorSitesMatrix = [ 14 | { 15 | protocol: "https", 16 | url: "https://iptv.b2og.com", 17 | frequence: "per 2h", 18 | idc: "腾讯云", 19 | provider: "[GrandDuke1106](https://github.com/GrandDuke1106)", 20 | }, 21 | { 22 | protocol: "https", 23 | url: "https://iptv.helima.net", 24 | frequence: "per 2.5h", 25 | idc: "Oracle", 26 | provider: "[DobySAMA](https://github.com/DobySAMA)", 27 | }, 28 | { 29 | protocol: "https", 30 | url: "https://m3u.002397.xyz", 31 | frequence: "per 2h", 32 | idc: "CloudFlare Tunnel", 33 | provider: "[Eternal-Future](https://github.com/Eternal-Future)", 34 | }, 35 | { 36 | protocol: "https", 37 | url: "https://iptv.002397.xyz", 38 | frequence: "per 2h", 39 | idc: "Amazon", 40 | provider: "[Eternal-Future](https://github.com/Eternal-Future)", 41 | }, 42 | ] 43 | export const get_custom_url = () => 44 | !!process.env.CUSTOM_URL ? process.env.CUSTOM_URL : "https://m3u.ibert.me" 45 | 46 | export const get_rollback_urls = () => { 47 | const matrix_url = sites_matrix.map((m) => m.url) 48 | 49 | if (!process.env.ROLLBACK_URLS) { 50 | return ["https://m3u.ibert.me", ...matrix_url] 51 | } 52 | 53 | return process.env.ROLLBACK_URLS.split(",") 54 | .map((url) => url.trim()) 55 | .concat(["https://m3u.ibert.me", ...matrix_url]) 56 | } 57 | 58 | export const get_github_raw_proxy_url = () => { 59 | const custom = process.env.CUSTOM_GITHUB_RAW_SOURCE_PROXY_URL 60 | return !!custom ? custom : `https://ghfast.top` 61 | } 62 | 63 | export const replace_github_raw_proxy_url = (s: string) => { 64 | const proxy_url = get_github_raw_proxy_url() 65 | return s.replace( 66 | /tvg\-logo="https:\/\/raw\.githubusercontent\.com\//g, 67 | `tvg-logo="${proxy_url}/https://raw.githubusercontent.com/` 68 | ) 69 | } 70 | 71 | export const is_filted_channels = (s: string) => { 72 | if (s.includes("ABN")) { 73 | return true 74 | } 75 | 76 | if (s.includes("NTD")) { 77 | return true 78 | } 79 | 80 | return false 81 | } -------------------------------------------------------------------------------- /src/sources/iptv_org.ts: -------------------------------------------------------------------------------- 1 | import { is_filted_channels, collectM3uSource, get_channel_id } from "../utils" 2 | import { converter, handle_m3u } from "./utils" 3 | import type { ISource, TSources } from "./utils" 4 | 5 | export const iptv_org_filter: ISource["filter"] = ( 6 | raw, 7 | caller, 8 | collectFn 9 | ): [string, number] => { 10 | const rawArray = handle_m3u(raw) 11 | const invalidExp = /\#EXTVLCOPT:/ 12 | 13 | const arr = rawArray.filter((r) => !invalidExp.test(r)) 14 | 15 | let sourced: string[] = [] 16 | let result = [arr[0]] 17 | 18 | for (let i = 1; i < arr.length; i += 2) { 19 | const id = get_channel_id(arr[i]) 20 | 21 | if (is_filted_channels(id.trim())) { 22 | continue 23 | } 24 | 25 | if (caller === "normal" && collectFn) { 26 | collectM3uSource(arr[i], arr[i + 1], collectFn) 27 | } 28 | 29 | if (!sourced.includes(id)) { 30 | sourced.push(id) 31 | result.push( 32 | arr[i] 33 | .replace(/\@\@[0-9]*/g, "") 34 | .replace(/\[geo\-blocked\]/, "") 35 | .replace(/\[Geo\-blocked\]/, "") 36 | .trim() 37 | ) 38 | result.push(arr[i + 1]) 39 | } 40 | } 41 | 42 | return [converter(result.join("\n")), (result.length - 1) / 2] 43 | } 44 | 45 | export const iptv_org_sources: TSources = [ 46 | { 47 | name: "iptv.org All", 48 | f_name: "o_all", 49 | url: "https://raw.githubusercontent.com/iptv-org/iptv/gh-pages/index.m3u", 50 | filter: iptv_org_filter, 51 | }, 52 | { 53 | name: "iptv.org China", 54 | f_name: "o_cn", 55 | url: "https://raw.githubusercontent.com/iptv-org/iptv/gh-pages/countries/cn.m3u", 56 | filter: iptv_org_filter, 57 | }, 58 | ] 59 | 60 | export const iptv_org_stream_sources: TSources = [ 61 | { 62 | name: "iptv.org stream China", 63 | f_name: "o_s_cn", 64 | url: "https://raw.githubusercontent.com/iptv-org/iptv/master/streams/cn.m3u", 65 | filter: iptv_org_filter, 66 | }, 67 | { 68 | name: "iptv.org stream China 112114", 69 | f_name: "o_s_cn_112114", 70 | url: "https://raw.githubusercontent.com/iptv-org/iptv/master/streams/cn_112114.m3u", 71 | filter: iptv_org_filter, 72 | }, 73 | { 74 | name: "iptv.org stream China CCTV", 75 | f_name: "o_s_cn_cctv", 76 | url: "https://raw.githubusercontent.com/iptv-org/iptv/master/streams/cn_cctv.m3u", 77 | filter: iptv_org_filter, 78 | }, 79 | { 80 | name: "iptv.org stream China CGTN", 81 | f_name: "o_s_cn_cgtn", 82 | url: "https://raw.githubusercontent.com/iptv-org/iptv/master/streams/cn_cgtn.m3u", 83 | filter: iptv_org_filter, 84 | }, 85 | ] 86 | -------------------------------------------------------------------------------- /src/rollback.ts: -------------------------------------------------------------------------------- 1 | import { hrtime } from "process" 2 | 3 | import { ISource } from "./sources" 4 | import { get_rollback_urls } from "./utils" 5 | import { TEPGSource } from "./epgs/utils" 6 | 7 | export const updateByRollback = async ( 8 | sr: ISource, 9 | sr_filter: ISource["filter"], 10 | idx: number = 0 11 | ): Promise<[string, number] | undefined> => { 12 | const rollback_urls = get_rollback_urls() 13 | try { 14 | const now = hrtime.bigint() 15 | const res = await fetch(`${rollback_urls[idx]}/${sr.f_name}.m3u`) 16 | if (res.ok) { 17 | console.log( 18 | `Fetch m3u from ${sr.name} with ROLLBACK from ${ 19 | rollback_urls[idx] 20 | } finished, cost ${ 21 | (parseInt(hrtime.bigint().toString()) - 22 | parseInt(now.toString())) / 23 | 10e6 24 | } ms` 25 | ) 26 | const text = await res.text() 27 | return sr_filter(text as string, "rollback") 28 | } 29 | 30 | console.log( 31 | `Fetch m3u Rollback from ${rollback_urls[idx]} FAILED, try next...` 32 | ) 33 | if (++idx < rollback_urls.length) { 34 | return updateByRollback(sr, sr_filter, idx) 35 | } 36 | 37 | console.log(`All failed, give up ${sr.name}!`) 38 | return undefined 39 | } catch (e) { 40 | console.log( 41 | `Fetch m3u Rollback from ${rollback_urls[idx]} FAILED, try next...` 42 | ) 43 | if (++idx < rollback_urls.length) { 44 | return updateByRollback(sr, sr_filter, idx) 45 | } 46 | 47 | console.log(`All failed, give up ${sr.name}!`) 48 | return undefined 49 | } 50 | } 51 | 52 | export const updateEPGByRollback = async ( 53 | sr: TEPGSource, 54 | idx: number = 0 55 | ): Promise => { 56 | const rollback_urls = get_rollback_urls() 57 | try { 58 | const now = hrtime.bigint() 59 | const res = await fetch(`${rollback_urls[idx]}/epg/${sr.f_name}.xml`) 60 | if (res.ok) { 61 | console.log( 62 | `Fetch EPG from ${sr.name} with ROLLBACK from ${ 63 | rollback_urls[idx] 64 | } finished, cost ${ 65 | (parseInt(hrtime.bigint().toString()) - 66 | parseInt(now.toString())) / 67 | 10e6 68 | } ms` 69 | ) 70 | return await res.text() 71 | } 72 | 73 | console.log( 74 | `Fetch EPG Rollback from ${rollback_urls[idx]} FAILED, try next...` 75 | ) 76 | if (++idx < rollback_urls.length) { 77 | return updateEPGByRollback(sr, idx) 78 | } 79 | 80 | console.log(`All failed, give up ${sr.name}!`) 81 | return undefined 82 | } catch (e) { 83 | console.log( 84 | `Fetch EPG Rollback from ${rollback_urls[idx]} FAILED, try next...` 85 | ) 86 | if (++idx < rollback_urls.length) { 87 | return updateEPGByRollback(sr, idx) 88 | } 89 | 90 | console.log(`All failed, give up ${sr.name}!`) 91 | return undefined 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/serve.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs" 2 | import path from "path" 3 | 4 | import Koa from "koa" 5 | import { default as Static } from "koa-static" 6 | import Router from "koa-router" 7 | import MarkdownIt from "markdown-it" 8 | 9 | import { canIUseIPTVChecker, canIUseM3uFile } from "./checker" 10 | 11 | const app = new Koa() 12 | const router = new Router() 13 | const md = new MarkdownIt({ html: true }) 14 | 15 | const markdownBody = (md_p: string, back_p: string) => { 16 | let markdown: string = "" 17 | if (!fs.existsSync(md_p)) { 18 | markdown = fs.readFileSync(back_p).toString() 19 | } else { 20 | markdown = fs.readFileSync(md_p).toString() 21 | } 22 | 23 | return ` 24 | 25 | 26 | 27 | 28 | 41 | 42 | 43 |
${md.render(markdown)}
44 | 45 | 46 | ` 47 | } 48 | 49 | app.use(Static("./m3u")) 50 | 51 | router.get("/", (ctx) => { 52 | const readme_p = path.resolve("m3u", "README.md") 53 | const back_readme_p = path.resolve("back", "README.md") 54 | 55 | ctx.body = markdownBody(readme_p, back_readme_p) 56 | }) 57 | 58 | router.get("/list/:channel", (ctx) => { 59 | const list = ctx.params.channel 60 | const list_readme_p = path.resolve("m3u", "list", `${list}.md`) 61 | const back_list_readme_p = path.resolve("back", "list", `${list}.md`) 62 | 63 | ctx.body = markdownBody(list_readme_p, back_list_readme_p) 64 | }) 65 | 66 | router.get("/check/:channel", async (ctx) => { 67 | const chan = ctx.params.channel 68 | 69 | if (!canIUseM3uFile(`${chan}.m3u`)) { 70 | ctx.status = 404 71 | return 72 | } 73 | 74 | if (!(await canIUseIPTVChecker())) { 75 | ctx.status = 403 76 | return 77 | } 78 | 79 | ctx.body = fs.readFileSync(path.resolve("public", "check.html")).toString() 80 | }) 81 | 82 | router.get("/api/check", async (ctx) => { 83 | if (!(await canIUseIPTVChecker())) { 84 | ctx.status = 403 85 | return 86 | } 87 | 88 | const { url, timeout } = ctx.query 89 | if (!url) { 90 | ctx.status = 403 91 | return 92 | } 93 | 94 | try { 95 | const t = parseInt(timeout as string, 10) 96 | const res = await fetch( 97 | `${ 98 | process.env.IPTV_CHECKER_URL 99 | }/check/url-is-available?url=${url}&timeout=${isNaN(t) ? -1 : t}` 100 | ) 101 | 102 | ctx.status = res.status 103 | ctx.body = await res.text() 104 | } catch (e) { 105 | ctx.status = 500 106 | return 107 | } 108 | }) 109 | 110 | app.use(router.routes()) 111 | 112 | app.listen(8080, () => { 113 | console.log("Serving at http://127.0.0.1:8080") 114 | console.log("If the network supports ipv6, visit http://[::1]:8080") 115 | }) 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iptv-sources 2 | 3 | Autoupdate iptv sources 4 | 5 | [![Docker Build](https://img.shields.io/docker/automated/herberthe0229/iptv-sources?style=flat-square)](https://hub.docker.com/r/herberthe0229/iptv-sources) 6 | [![Docker Version](https://img.shields.io/docker/v/herberthe0229/iptv-sources/latest?style=flat-square)](https://hub.docker.com/r/herberthe0229/iptv-sources) 7 | [![Docker Image](https://img.shields.io/docker/image-size/herberthe0229/iptv-sources/latest?style=flat-square)](https://hub.docker.com/r/herberthe0229/iptv-sources) 8 | [![Docker Pulls](https://img.shields.io/docker/pulls/herberthe0229/iptv-sources?style=flat-square)](https://hub.docker.com/r/herberthe0229/iptv-sources) 9 | [![Docker Stars](https://img.shields.io/docker/stars/herberthe0229/iptv-sources?style=flat-square)](https://hub.docker.com/r/herberthe0229/iptv-sources) 10 | 11 | Join discord: [![Discord](https://discord.badge.ibert.me/api/server/betxHcsTqa)](https://discord.gg/betxHcsTqa) 12 | 13 | Sources are from: 14 | 15 | - 16 | - [iptv.org](https://github.com/iptv-org/iptv) 17 | - [YueChan/Live](https://github.com/YueChan/Live) 18 | - [YanG-1989/m3u](https://github.com/YanG-1989/m3u) 19 | - [fanmingming/live](https://github.com/fanmingming/live) 20 | - [qwerttvv/Beijing-IPTV](https://github.com/qwerttvv/Beijing-IPTV) 21 | - [joevess/IPTV](https://github.com/joevess/IPTV) 22 | - [cymz6/AutoIPTV-Hotel](https://github.com/cymz6/AutoIPTV-Hotel) 23 | 24 | EPG Sources are from: 25 | 26 | - [fanmingming/live](https://github.com/fanmingming/live) 27 | - [112114.xyz](https://diyp1.112114.xyz) 28 | - [epg.51zmt.top:8000](http://epg.51zmt.top:8000/) 29 | 30 | See to get more. 31 | 32 | ## Deploy by yourself 33 | 34 | - [How to deploy with GitHub Pages](https://github.com/HerbertHe/iptv-sources/discussions/35) 35 | - [How to deploy with docker](https://github.com/HerbertHe/iptv-sources/discussions/36) 36 | - [How to deploy with nodejs](https://github.com/HerbertHe/iptv-sources/discussions/37) 37 | 38 | ## Supported Environment Variables 39 | 40 | ```shell 41 | # add custom rollback urls, default is empty 42 | # ROLLBACK_URLS=https://xxxx.xxx.com 43 | 44 | # close source proxy, default is false 45 | # CLOSE_SOURCE_PROXY=true 46 | 47 | # add custom github raw source proxy url 48 | # The custom proxy service you configured MUST supports the request urls, like `${CUSTOM_GITHUB_RAW_SOURCE_PROXY_URL}/https://raw.githubusercontent.com/xxx/xxx` 49 | # If you want to deploy the ghproxy by yourself, see https://github.com/hunshcn/gh-proxy 50 | # CUSTOM_GITHUB_RAW_SOURCE_PROXY_URL=https://ghp.ci/ 51 | 52 | # enable iptv checker, default is false 53 | # ENABLE_IPTV_CHECKER=true 54 | 55 | # add iptv checker url, default is empty 56 | # IPTV_CHECKER_URL=http://[::1]:8081 57 | ``` 58 | 59 | ## Q&A 60 | 61 | - [How to close the github raw content proxy](https://github.com/HerbertHe/iptv-sources/discussions/38) 62 | - [How to set the custom github raw source proxy url](https://github.com/HerbertHe/iptv-sources/discussions/39) 63 | - [How to use `iptv-checker` feature](https://github.com/HerbertHe/iptv-sources/discussions/40) 64 | - [How to add your own rollback urls](https://github.com/HerbertHe/iptv-sources/discussions/41) 65 | - [How to create custom sources based on the upstream](https://github.com/HerbertHe/iptv-sources/discussions/68) 66 | 67 | ## Star History 68 | 69 | [![Star History Chart](https://api.star-history.com/svg?repos=HerbertHe/iptv-sources&type=Date)](https://star-history.com/#HerbertHe/iptv-sources&Date) 70 | 71 | ## LICENSE 72 | 73 | GPL-3.0 © Herbert He 74 | 75 | 本项目基于 GPL-3.0 协议开源。 76 | -------------------------------------------------------------------------------- /public/check.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sources Checker 7 | 8 | 9 |
10 |

11 |
12 |

13 | Powered by 14 | 15 | iptv-checker © UNLICENSED 16 | 17 |

18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
No.NameAvailable
29 |
30 | 31 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /src/file.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs" 2 | import path from "path" 3 | import { hrtime } from "process" 4 | 5 | import { with_github_raw_url_proxy } from "./sources" 6 | import { m3u2txt } from "./utils" 7 | import type { ISource } from "./sources" 8 | import type { TEPGSource } from "./epgs/utils" 9 | 10 | export const getContent = async (src: ISource | TEPGSource) => { 11 | const now = hrtime.bigint() 12 | const url = /^https:\/\/raw.githubusercontent.com\//.test(src.url) 13 | ? with_github_raw_url_proxy(src.url) 14 | : src.url 15 | 16 | const res = await fetch(url) 17 | return [res.ok, await res.text(), now] 18 | } 19 | 20 | export const writeM3u = (name: string, m3u: string) => { 21 | if (!fs.existsSync(path.join(path.resolve(), "m3u"))) { 22 | fs.mkdirSync(path.join(path.resolve(), "m3u")) 23 | } 24 | 25 | fs.writeFileSync(path.join(path.resolve(), "m3u", `${name}.m3u`), m3u) 26 | } 27 | 28 | export const writeSources = ( 29 | name: string, 30 | f_name: string, 31 | sources: Map 32 | ) => { 33 | let srcs = {} 34 | for (const [k, v] of sources) { 35 | srcs[k] = v 36 | } 37 | 38 | if (!fs.existsSync(path.resolve("m3u", "sources"))) { 39 | fs.mkdirSync(path.resolve("m3u", "sources")) 40 | } 41 | 42 | fs.writeFileSync( 43 | path.resolve("m3u", "sources", `${f_name}.json`), 44 | JSON.stringify({ 45 | name, 46 | sources: srcs, 47 | }) 48 | ) 49 | } 50 | 51 | export const writeM3uToTxt = (name: string, f_name: string, m3u: string) => { 52 | const m3uArray = m3u.split("\n") 53 | let txt = m3u2txt(m3uArray) 54 | 55 | if (!fs.existsSync(path.join(path.resolve(), "m3u", "txt"))) { 56 | fs.mkdirSync(path.join(path.resolve(), "m3u", "txt")) 57 | } 58 | 59 | fs.writeFileSync( 60 | path.join(path.resolve(), "m3u", "txt", `${f_name}.txt`), 61 | txt 62 | ) 63 | } 64 | 65 | export const mergeTxts = () => { 66 | const txts_p = path.resolve("m3u", "txt") 67 | 68 | const files = fs.readdirSync(txts_p) 69 | 70 | const txts = files 71 | .map((d) => fs.readFileSync(path.join(txts_p, d).toString())) 72 | .join("\n") 73 | 74 | fs.writeFileSync(path.join(txts_p, "merged.txt"), txts) 75 | } 76 | 77 | export const mergeSources = () => { 78 | const sources_p = path.resolve("m3u", "sources") 79 | 80 | const files = fs.readdirSync(sources_p) 81 | 82 | const res = { 83 | name: "Sources", 84 | sources: {}, 85 | } 86 | 87 | files.forEach((f) => { 88 | const so = JSON.parse( 89 | fs.readFileSync(path.join(sources_p, f), "utf-8") 90 | ).sources 91 | 92 | Object.keys(so).forEach((k) => { 93 | if (!res.sources[k]) { 94 | res.sources[k] = so[k] 95 | } else { 96 | res.sources[k] = [...new Set([...res.sources[k], ...so[k]])] 97 | } 98 | }) 99 | }) 100 | 101 | fs.writeFileSync(path.join(sources_p, "sources.json"), JSON.stringify(res)) 102 | } 103 | 104 | export const writeEpgXML = (f_name: string, xml: string) => { 105 | if (!fs.existsSync(path.join(path.resolve(), "m3u", "epg"))) { 106 | fs.mkdirSync(path.join(path.resolve(), "m3u", "epg")) 107 | } 108 | 109 | fs.writeFileSync(path.resolve("m3u", "epg", `${f_name}.xml`), xml) 110 | } 111 | 112 | const cleanDir = (p: string) => { 113 | if (fs.existsSync(p)) { 114 | fs.readdirSync(p).forEach((file) => { 115 | const isDir = fs.statSync(path.join(p, file)).isDirectory() 116 | if (isDir) { 117 | cleanDir(path.join(p, file)) 118 | } else { 119 | fs.unlinkSync(path.join(p, file)) 120 | } 121 | }) 122 | } 123 | } 124 | 125 | export const cleanFiles = () => cleanDir(path.join(path.resolve(), "m3u")) 126 | -------------------------------------------------------------------------------- /src/readme.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs" 2 | import path from "path" 3 | 4 | import { handle_m3u } from "./sources" 5 | import type { TEPGSource } from "./epgs/utils" 6 | import { get_from_info } from "./utils" 7 | 8 | export interface IREADMESource { 9 | name: string 10 | f_name: string 11 | count?: number | undefined 12 | } 13 | 14 | export type TREADMESources = IREADMESource[] 15 | export type TREADMEEPGSources = TEPGSource[] 16 | 17 | export const updateChannelList = ( 18 | name: string, 19 | f_name: string, 20 | m3u: string, 21 | rollback: boolean = false 22 | ) => { 23 | const list_temp_p = path.join(path.resolve(), "LIST.temp.md") 24 | const list = fs.readFileSync(list_temp_p, "utf8").toString() 25 | 26 | const m3uArray = handle_m3u(m3u) 27 | const channelRegExp = /\#EXTINF:-1([^,]*),(.*)/ 28 | let i = 1 29 | let channels: Array[] = [] 30 | while (i < m3uArray.length) { 31 | const reg = channelRegExp.exec(m3uArray[i]) as RegExpExecArray 32 | channels.push([ 33 | reg[2].replace(/\|/g, "").trim(), 34 | get_from_info(m3uArray[i + 1]), 35 | m3uArray[i + 1], 36 | ]) 37 | i += 2 38 | } 39 | 40 | const after = list 41 | .replace( 42 | "", 43 | `# List for **${name}**${ 44 | rollback ? "(Rollback)" : "" 45 | }\n\n> M3U: [${f_name}.m3u](/${f_name}.m3u), TXT: [${f_name}.txt](/txt/${f_name}.txt)` 46 | ) 47 | .replace( 48 | "", 49 | `${channels 50 | ?.map( 51 | (c, idx) => 52 | `| ${idx + 1} | ${c[0].replace("|", "")} | ${c[1]} | <${ 53 | c[2] 54 | }> |` 55 | ) 56 | .join("\n")}\n\nUpdated at **${new Date()}**` 57 | ) 58 | 59 | const list_p = path.join(path.resolve(), "m3u", "list") 60 | 61 | if (!fs.existsSync(list_p)) { 62 | fs.mkdirSync(list_p) 63 | } 64 | 65 | fs.writeFileSync(path.join(list_p, `${f_name}.list.md`), after) 66 | } 67 | 68 | export const updateReadme = ( 69 | sources: TREADMESources, 70 | sources_res: Array<[string, number | undefined]>, 71 | epgs: TREADMEEPGSources, 72 | epgs_res: Array<[string | undefined]> 73 | ) => { 74 | const readme_temp_p = path.join(path.resolve(), "README.temp.md") 75 | const readme = fs.readFileSync(readme_temp_p, "utf8").toString() 76 | 77 | const after = readme 78 | .replace( 79 | "", 80 | `${sources 81 | ?.map( 82 | (s, idx) => 83 | `| ${s.name} | [${s.f_name}.m3u](/${ 84 | s.f_name 85 | }.m3u)
[${s.f_name}.txt](/txt/${ 86 | s.f_name 87 | }.txt) | [List for ${s.name}](/list/${ 88 | s.f_name 89 | }.list) | ${ 90 | sources_res?.[idx]?.[1] === undefined 91 | ? "update failed" 92 | : sources_res[idx][1] 93 | } | ${ 94 | sources_res?.[idx]?.[0] === "rollback" ? "✅" : "-" 95 | } |` 96 | ) 97 | .join("\n")}` 98 | ) 99 | .replace( 100 | "", 101 | `${epgs 102 | ?.map( 103 | (e, idx) => 104 | `| ${e.name} | [${e.f_name}.xml](/epg/${ 105 | e.f_name 106 | }.xml) | ${ 107 | !!epgs_res?.[idx]?.[0] 108 | ? epgs_res?.[idx]?.[0] === "rollback" 109 | ? "✅" 110 | : "-" 111 | : "update failed" 112 | } |` 113 | ) 114 | .join("\n")}\n\nUpdated at **${new Date()}**` 115 | ) 116 | 117 | if (!fs.existsSync(path.join(path.resolve(), "m3u"))) { 118 | fs.mkdirSync(path.join(path.resolve(), "m3u")) 119 | } 120 | 121 | fs.writeFileSync(path.join(path.resolve(), "m3u", "README.md"), after) 122 | } 123 | -------------------------------------------------------------------------------- /src/task/custom/handler.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs" 2 | import path from "path" 3 | 4 | import type { ICustom, ICustomRuleReplacerItem } from "./define" 5 | import { config_path, m3u_path, write_custom_path } from "../const" 6 | import { m3u2txt, trimAny } from "../../utils" 7 | 8 | const loadConfigCustom = (): ICustom | undefined => { 9 | if (!fs.existsSync(config_path)) { 10 | return void 0 11 | } 12 | 13 | if (fs.readdirSync(config_path).length === 0) { 14 | return void 0 15 | } 16 | 17 | const cfg = JSON.parse( 18 | fs.readFileSync(path.join(config_path, "custom.json"), "utf-8") 19 | ) as ICustom 20 | 21 | // 去除不必要的空格 22 | cfg.rules = trimAny(cfg.rules) 23 | 24 | return cfg 25 | } 26 | 27 | const getFilenames = () => { 28 | return fs 29 | .readdirSync(path.join(m3u_path, "txt")) 30 | .map((f) => f.replace(".txt", "")) 31 | .filter((f) => f !== "channels") 32 | } 33 | 34 | const after_replaced = ( 35 | value: string, 36 | replacers?: ICustomRuleReplacerItem[] 37 | ) => { 38 | if (!replacers || !Array.isArray(replacers) || replacers.length === 0) 39 | return value 40 | 41 | const replacer = replacers?.find((e) => { 42 | if ( 43 | e.type === "regexp" && 44 | !!e.pattern && 45 | !!e.flags && 46 | !!e.target && 47 | new RegExp(e.pattern, e.flags).test(value) 48 | ) { 49 | return true 50 | } 51 | 52 | if ( 53 | e.type === "string" && 54 | !!e.pattern && 55 | e.target && 56 | value.includes(e.pattern) 57 | ) { 58 | return true 59 | } 60 | 61 | return false 62 | }) 63 | 64 | if (!!replacer && replacer.type === "regexp") { 65 | return value.replace( 66 | new RegExp(replacer.pattern, replacer.flags), 67 | replacer.target 68 | ) 69 | } 70 | 71 | if (!!replacer && replacer.type === "string") { 72 | return value.replace(replacer.pattern, replacer.target) 73 | } 74 | 75 | return value 76 | } 77 | 78 | export const runCustomTask = () => { 79 | const cfg = loadConfigCustom() 80 | 81 | if (!cfg) return 82 | 83 | if (!cfg.rules || cfg.rules.length === 0) return 84 | 85 | if (!fs.existsSync(write_custom_path)) { 86 | fs.mkdirSync(write_custom_path) 87 | } 88 | 89 | const files = getFilenames() 90 | 91 | const rules = cfg.rules.filter((r) => files.includes(r.upstream.trim())) 92 | 93 | const ruled = rules.map((r) => r.upstream) 94 | 95 | files.forEach((f) => { 96 | if (!ruled.includes(f)) return 97 | 98 | const r = rules.filter((ru) => ru.upstream === f) 99 | 100 | if (r.length === 0) return 101 | 102 | console.log(`Customize Source ${f}`) 103 | 104 | const arr = fs 105 | .readFileSync(path.join(m3u_path, `${f}.m3u`), "utf-8") 106 | .split("\n") 107 | let res = [arr[0]] 108 | 109 | r.forEach((rr) => { 110 | for (let i = 1; i < arr.length; i += 2) { 111 | const regExp = /\#EXTINF:-1([^,]*),(.*)/ 112 | 113 | const name = regExp.exec(arr[i])![2].trim() 114 | 115 | // include 的优先级高于 exclude 116 | if (!!rr.include && Array.isArray(rr.include)) { 117 | if (rr.include.includes(name)) { 118 | let _extinf = arr[i] 119 | let _url = arr[i + 1] 120 | if (!!rr.replacer) { 121 | const { 122 | extinf: extinf_replacer, 123 | url: url_replacer, 124 | } = rr.replacer 125 | _extinf = after_replaced(arr[i], extinf_replacer) 126 | _url = after_replaced(arr[i + 1], url_replacer) 127 | } 128 | res.push(_extinf) 129 | res.push(_url) 130 | } 131 | } else if (!!rr.exclude && Array.isArray(rr.exclude)) { 132 | if (!rr.exclude.includes(name)) { 133 | let _extinf = arr[i] 134 | let _url = arr[i + 1] 135 | if (!!rr.replacer) { 136 | const { 137 | extinf: extinf_replacer, 138 | url: url_replacer, 139 | } = rr.replacer 140 | _extinf = after_replaced(arr[i], extinf_replacer) 141 | _url = after_replaced(arr[i + 1], url_replacer) 142 | } 143 | res.push(_extinf) 144 | res.push(_url) 145 | } 146 | } else { 147 | let _extinf = arr[i] 148 | let _url = arr[i + 1] 149 | if (!!rr.replacer) { 150 | const { extinf: extinf_replacer, url: url_replacer } = 151 | rr.replacer 152 | _extinf = after_replaced(arr[i], extinf_replacer) 153 | _url = after_replaced(arr[i + 1], url_replacer) 154 | } 155 | res.push(_extinf) 156 | res.push(_url) 157 | } 158 | } 159 | 160 | if (!!rr.append && Array.isArray(rr.append)) { 161 | rr.append.forEach(({ name, url, extinf }) => { 162 | if (!!extinf) { 163 | res.push(extinf) 164 | } else { 165 | let _name = name.trim() 166 | res.push( 167 | `#EXTINF:-1 tvg-name="${_name}" tvg-id="${_name}" group-title="Custom",${_name}` 168 | ) 169 | } 170 | 171 | res.push(url) 172 | }) 173 | } 174 | }) 175 | 176 | fs.writeFileSync( 177 | path.join(write_custom_path, `${f}.m3u`), 178 | res.join("\n") 179 | ) 180 | 181 | fs.writeFileSync(path.join(write_custom_path, `${f}.txt`), m3u2txt(res)) 182 | }) 183 | } 184 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { hrtime } from "process" 2 | 3 | import { updateChannelsJson } from "./channels" 4 | import { 5 | cleanFiles, 6 | getContent, 7 | mergeSources, 8 | mergeTxts, 9 | writeEpgXML, 10 | writeM3u, 11 | writeM3uToTxt, 12 | writeSources, 13 | } from "./file" 14 | import { updateChannelList, updateReadme } from "./readme" 15 | import { sources } from "./sources" 16 | import { updateByRollback, updateEPGByRollback } from "./rollback" 17 | import { epgs_sources } from "./epgs" 18 | import { writeTvBoxJson } from "./tvbox" 19 | import { Collector } from "./utils" 20 | import { runCustomTask } from "./task/custom" 21 | 22 | cleanFiles() 23 | 24 | // 执行脚本 25 | Promise.allSettled( 26 | sources.map(async (sr) => { 27 | console.log(`[TASK] Fetch ${sr.name}`) 28 | try { 29 | const [ok, text, now] = await getContent(sr) 30 | if (ok && !!text) { 31 | console.log( 32 | `Fetch m3u from ${sr.name} finished, cost ${ 33 | (parseInt(hrtime.bigint().toString()) - 34 | parseInt(now.toString())) / 35 | 10e6 36 | } ms` 37 | ) 38 | 39 | const sourcesCollector = Collector( 40 | undefined, 41 | (v) => !/^([a-z]+)\:\/\//.test(v) 42 | ) 43 | 44 | let [m3u, count] = sr.filter( 45 | text as string, 46 | ["o_all", "all"].includes(sr.f_name) ? "skip" : "normal", 47 | sourcesCollector.collect 48 | ) 49 | 50 | writeM3u(sr.f_name, m3u) 51 | writeM3uToTxt(sr.name, sr.f_name, m3u) 52 | writeSources(sr.name, sr.f_name, sourcesCollector.result()) 53 | writeTvBoxJson( 54 | sr.f_name, 55 | [{ name: sr.name, f_name: sr.f_name }], 56 | sr.name 57 | ) 58 | updateChannelList(sr.name, sr.f_name, m3u) 59 | return ["normal", count] 60 | } else { 61 | // rollback 62 | const res = await updateByRollback(sr, sr.filter) 63 | if (!!res) { 64 | const [m3u, count] = res 65 | writeM3u(sr.f_name, m3u) 66 | writeM3uToTxt(sr.name, sr.f_name, m3u) 67 | writeTvBoxJson( 68 | sr.f_name, 69 | [{ name: sr.name, f_name: sr.f_name }], 70 | sr.name 71 | ) 72 | updateChannelList(sr.name, sr.f_name, m3u, true) 73 | return ["rollback", count] 74 | } else { 75 | // rollback failed 76 | console.log(`[WARNING] m3u ${sr.name} get failed!`) 77 | return ["rollback", void 0] 78 | } 79 | } 80 | } catch (e) { 81 | console.log(e) 82 | const res = await updateByRollback(sr, sr.filter) 83 | if (!!res) { 84 | const [m3u, count] = res 85 | writeM3u(sr.f_name, m3u) 86 | writeM3uToTxt(sr.name, sr.f_name, m3u) 87 | writeTvBoxJson( 88 | sr.f_name, 89 | [{ name: sr.name, f_name: sr.f_name }], 90 | sr.name 91 | ) 92 | updateChannelList(sr.name, sr.f_name, m3u, true) 93 | return ["rollback", count] 94 | } else { 95 | // rollback failed 96 | console.log(`[WARNING] m3u ${sr.name} get failed!`) 97 | return ["rollback", void 0] 98 | } 99 | } 100 | }) 101 | ) 102 | .then(async (result) => { 103 | const epgs = await Promise.allSettled( 104 | epgs_sources.map(async (epg_sr) => { 105 | console.log(`[TASK] Fetch EPG ${epg_sr.name}`) 106 | try { 107 | const [ok, text, now] = await getContent(epg_sr) 108 | 109 | if (ok && !!text) { 110 | console.log( 111 | `Fetch EPG from ${epg_sr.name} finished, cost ${ 112 | (parseInt(hrtime.bigint().toString()) - 113 | parseInt(now.toString())) / 114 | 10e6 115 | } ms` 116 | ) 117 | writeEpgXML(epg_sr.f_name, text as string) 118 | return ["normal"] 119 | } else { 120 | // rollback 121 | const text = await updateEPGByRollback(epg_sr) 122 | if (!!text) { 123 | writeEpgXML(epg_sr.f_name, text as string) 124 | return ["rollback"] 125 | } else { 126 | // rollback failed 127 | console.log( 128 | `[WARNING] EPG ${epg_sr.name} get failed!` 129 | ) 130 | return [void 0] 131 | } 132 | } 133 | } catch (e) { 134 | const text = await updateEPGByRollback(epg_sr) 135 | if (!!text) { 136 | writeEpgXML(epg_sr.f_name, text as string) 137 | return ["rollback"] 138 | } else { 139 | // rollback failed 140 | console.log(`[WARNING] EPG ${epg_sr.name} get failed!`) 141 | return [void 0] 142 | } 143 | } 144 | }) 145 | ) 146 | 147 | return { 148 | sources: result, 149 | epgs: epgs, 150 | } 151 | }) 152 | .then((result) => { 153 | console.log(`[TASK] Write important files`) 154 | const sources_res = result.sources.map((r) => (r).value) 155 | const epgs_res = result.epgs.map((r) => (r).value) 156 | mergeTxts() 157 | mergeSources() 158 | writeTvBoxJson("tvbox", sources, "Channels") 159 | updateChannelsJson(sources, sources_res, epgs_sources) 160 | updateReadme(sources, sources_res, epgs_sources, epgs_res) 161 | }) 162 | .then(() => { 163 | console.log(`[TASK] Make custom sources`) 164 | runCustomTask() 165 | }) 166 | .catch((err) => { 167 | console.error(err) 168 | }) 169 | -------------------------------------------------------------------------------- /src/utils/const.ts: -------------------------------------------------------------------------------- 1 | export const channels_logo = [ 2 | "4K电影", 3 | "AMC", 4 | "ANIMAX", 5 | "ANIMAXHD", 6 | "AXN", 7 | "AnimalPlanet", 8 | "ArirangTV", 9 | "BBCEarth", 10 | "BBCLifestyle", 11 | "BBCWORLDNEWSASIA", 12 | "BLUEAntExtreme", 13 | "BOOMERANG", 14 | "BabyFirst", 15 | "BabyTV", 16 | "BeautifulLife", 17 | "BloombergTV", 18 | "BlueAntEntertainment", 19 | "CBN幸福剧场", 20 | "CBeebies", 21 | "CCTV1", 22 | "CCTV10", 23 | "CCTV11", 24 | "CCTV12", 25 | "CCTV13", 26 | "CCTV14", 27 | "CCTV15", 28 | "CCTV16", 29 | "CCTV17", 30 | "CCTV2", 31 | "CCTV3", 32 | "CCTV3D", 33 | "CCTV4", 34 | "CCTV4AME", 35 | "CCTV4EUO", 36 | "CCTV4K", 37 | "CCTV4欧洲", 38 | "CCTV4美洲", 39 | "CCTV5+", 40 | "CCTV5", 41 | "CCTV6", 42 | "CCTV7", 43 | "CCTV8", 44 | "CCTV8K", 45 | "CCTV9", 46 | "CETV1", 47 | "CETV2", 48 | "CETV3", 49 | "CETV4", 50 | "CGTN", 51 | "CGTNDoc", 52 | "CGTN俄语", 53 | "CGTN法语", 54 | "CGTN纪录", 55 | "CGTN西语", 56 | "CGTN记录", 57 | "CGTN阿语", 58 | "CHC动作电影", 59 | "CHC家庭影院", 60 | "CHC高清电影", 61 | "CI罪案侦查频道", 62 | "CNBC", 63 | "CNBCASIA财经台", 64 | "CNC", 65 | "CNCartoon", 66 | "CNN", 67 | "CNNNews", 68 | "CS", 69 | "CTS", 70 | "ChampionTV1", 71 | "ChampionTV2", 72 | "ChengSinTV", 73 | "ChengTeTV", 74 | "CinemaxHD", 75 | "CosmosBuddhistMissionaryTV", 76 | "CostarTV", 77 | "CrimeInvestigation", 78 | "CtiEntertainment", 79 | "CtiVariety", 80 | "DIVA", 81 | "DMAX", 82 | "DOX-CINEMA", 83 | "DOXTV", 84 | "DOX_YAQU", 85 | "DOX_xinzhi", 86 | "DW", 87 | "DaliTV", 88 | "Discovery-Asia", 89 | "DiscoveryHD", 90 | "Discovery科学", 91 | "Disney", 92 | "DisneyJunior", 93 | "EBCDrama", 94 | "EBCFinancialNews", 95 | "EBCMovies", 96 | "EBCNews", 97 | "EBCSuper", 98 | "EBCVariety", 99 | "EBCWesternMovies", 100 | "EBCYoYoTV", 101 | "EFTV", 102 | "ELEVENsports1", 103 | "ELTA_Ent", 104 | "ELTV生活英语台", 105 | "EVE", 106 | "EbcAsiaNews", 107 | "EbcAsiaWeishi", 108 | "FOXHD", 109 | "FOXMOVIES", 110 | "FOXSports", 111 | "FOXSports2", 112 | "FTV", 113 | "FTVNews", 114 | "FXHD", 115 | "FoodNetwork", 116 | "FoxFamilyMovies", 117 | "FoxLive", 118 | "FoxSports3", 119 | "GDTV3", 120 | "GDTV4", 121 | "GDTV6", 122 | "GDTV8", 123 | "GDTVECO", 124 | "GDTVENT", 125 | "GDTVMOV", 126 | "GDTVSHAO", 127 | "GTVDramaHD", 128 | "GTVEntertainment", 129 | "GTVOneHD", 130 | "GTVVarietyHD", 131 | "GlobalNews", 132 | "GoldSunTV", 133 | "GoodTV", 134 | "GoodTV2", 135 | "G导视", 136 | "HBLS", 137 | "HBO", 138 | "HBOFamily", 139 | "HBOHD", 140 | "HBOHits", 141 | "HBOSignature", 142 | "HGTV", 143 | "HISTORY", 144 | "HITS", 145 | "HMC", 146 | "HUBEI2", 147 | "HUBEI3", 148 | "HUBEI4", 149 | "HUBEI5", 150 | "HUBEI7", 151 | "HUBEI8", 152 | "HakkaTV", 153 | "History2", 154 | "HistoryChannel", 155 | "History历史频道", 156 | "HwaZanTV", 157 | "IFUN动漫台", 158 | "IHOT爱世界", 159 | "IHOT爱体育", 160 | "IHOT爱动漫", 161 | "IHOT爱历史", 162 | "IHOT爱喜剧", 163 | "IHOT爱奇谈", 164 | "IHOT爱娱乐", 165 | "IHOT爱家庭", 166 | "IHOT爱幼教", 167 | "IHOT爱怀旧", 168 | "IHOT爱悬疑", 169 | "IHOT爱探索", 170 | "IHOT爱旅行", 171 | "IHOT爱时尚", 172 | "IHOT爱极限", 173 | "IHOT爱江湖", 174 | "IHOT爱浪漫", 175 | "IHOT爱猎奇", 176 | "IHOT爱玩具", 177 | "IHOT爱电竞", 178 | "IHOT爱科学", 179 | "IHOT爱科幻", 180 | "IHOT爱经典", 181 | "IHOT爱美食", 182 | "IHOT爱解密", 183 | "IHOT爱谍战", 184 | "IHOT爱赛车", 185 | "IHOT爱都市", 186 | "IHOT爱院线", 187 | "IHOT爱青春", 188 | "IPTV3+", 189 | "IPTV5+", 190 | "IPTV6+", 191 | "IPTV8+", 192 | "IPTVEFEL", 193 | "IPTV少儿动画", 194 | "IPTV热播剧场", 195 | "IPTV相声小品", 196 | "IPTV经典电影", 197 | "IPTV魅力时尚", 198 | "J2", 199 | "JETVariety", 200 | "KMTV", 201 | "LNSY1", 202 | "LNTV-FINANCE", 203 | "LNTV-SPORT", 204 | "LNTV2", 205 | "LNTV3", 206 | "LNTV5", 207 | "LNTV6", 208 | "LNTV7", 209 | "LNTV8", 210 | "LSTIME", 211 | "Lifetime", 212 | "LoveNature", 213 | "MAX极速汽车", 214 | "MOMOkids", 215 | "MTV", 216 | "MTVLive", 217 | "MyCinemaEurope", 218 | "NEWTV东北热剧", 219 | "NEWTV中国功夫", 220 | "NEWTV军事评论", 221 | "NEWTV军旅剧场", 222 | "NEWTV古装剧场", 223 | "NEWTV家庭剧场", 224 | "NEWTV明星大片", 225 | "NEWTV欢乐剧场", 226 | "NEWTV武博世界", 227 | "NEWTV海外剧场", 228 | "NEWTV潮妈辣婆", 229 | "NEWTV炫舞未来", 230 | "NEWTV精品体育", 231 | "NEWTV精品大剧", 232 | "NEWTV精品纪录", 233 | "NEWTV超级体育", 234 | "NEWTV超级电影", 235 | "NEWTV超级电视剧", 236 | "NEWTV超级综艺", 237 | "NEWTV金牌综艺", 238 | "NEXTTVMovie", 239 | "NEXTTVZonghe", 240 | "NHK", 241 | "NHKWorld", 242 | "NOW新闻台", 243 | "NextTVNews", 244 | "NickJr", 245 | "Nickelodeon", 246 | "PiliPuppet", 247 | "PublicTV", 248 | "PublicTV2", 249 | "PublicTV3HD", 250 | "RTDoc", 251 | "RTHK31", 252 | "RTHK32", 253 | "RTNews", 254 | "SBN", 255 | "SETCity", 256 | "SETInews", 257 | "SETNews", 258 | "SETTaiwan", 259 | "SETZonghe", 260 | "SITV七彩戏剧", 261 | "SITV劲爆体育", 262 | "SITV极速汽车", 263 | "SITV法治天地", 264 | "SITV都市剧场", 265 | "SITV金色学堂", 266 | "SinDaTV", 267 | "SinJiTVHD", 268 | "SkyNews", 269 | "Smart知识台", 270 | "StarChineseMovies", 271 | "StarMoviesHD", 272 | "TACT", 273 | "TOPTVHD", 274 | "TRACESportStars", 275 | "TRT-World", 276 | "TVBJ2", 277 | "TVBS", 278 | "TVBS亚洲", 279 | "TVBS新闻", 280 | "TVBS欢乐", 281 | "TVBS精采", 282 | "TVBclassic", 283 | "TVB明珠台", 284 | "TVB星河", 285 | "TVB翡翠台", 286 | "TaiwanPlus", 287 | "ThaiPBS", 288 | "TienLiangTVHD", 289 | "UniqueNews", 290 | "UniqueUSTVHDUSTVHD", 291 | "VOA美国之音", 292 | "VideolandDrama", 293 | "VideolandJapanese", 294 | "VideolandMaxTV", 295 | "VideolandMovies", 296 | "VideolandOnTV", 297 | "VideolandSportsHD", 298 | "WETV", 299 | "WHTV1", 300 | "WHTV2", 301 | "WHTV3", 302 | "WHTV4", 303 | "WHTV5", 304 | "WHTV6", 305 | "WHTV7", 306 | "WarnerTV", 307 | "XFBY", 308 | "YANBIAN1", 309 | "ZChannel", 310 | "abcaus", 311 | "afc", 312 | "aljazeera", 313 | "anhui", 314 | "asiatravel", 315 | "asiazonghe", 316 | "beijing", 317 | "beijingjishi", 318 | "bestv", 319 | "bingtuan", 320 | "catchplay", 321 | "cdtv1", 322 | "cdtv2", 323 | "cdtv3", 324 | "cdtv4", 325 | "cdtv5", 326 | "cdtv6", 327 | "channelnewsasia", 328 | "channelv", 329 | "chongqing", 330 | "cinemaworld", 331 | "cmusic", 332 | "cnex", 333 | "cqccn", 334 | "daai", 335 | "daai2", 336 | "davinci", 337 | "dianjingtiantang", 338 | "discovery", 339 | "diyicaijing", 340 | "dongfang", 341 | "dongnan", 342 | "dox_juchang", 343 | "dox_xinyi", 344 | "dox_yijia", 345 | "dox_yinglun", 346 | "doxyinghua", 347 | "dreamworks", 348 | "eata_sports1", 349 | "eata_sports3", 350 | "elevensports2", 351 | "elta_sports2", 352 | "elta_yingju", 353 | "elta_zonghehd", 354 | "eltv", 355 | "emeidianying", 356 | "etoday", 357 | "euronews", 358 | "eurosport", 359 | "eyelvyou", 360 | "eyexiju", 361 | "fashionone", 362 | "fashiontv", 363 | "fenghuangxianggang", 364 | "fenghuangzhongwen", 365 | "fenghuangzixun", 366 | "fooldplanet", 367 | "france24", 368 | "ftv-1", 369 | "ftv-taiwan", 370 | "ftv-zongyi", 371 | "gansu", 372 | "gstv", 373 | "gtv_youxi", 374 | "guangdong", 375 | "guangxi", 376 | "guizhou", 377 | "hebei", 378 | "heilongjiang", 379 | "henan", 380 | "hkguojicaijing", 381 | "hks", 382 | "hongkong603", 383 | "hongkongkai", 384 | "huanghe", 385 | "huanxiao", 386 | "huanyucaijing", 387 | "huanyuzonghe", 388 | "huayi_yingju", 389 | "huayimbc", 390 | "hubei", 391 | "hunan", 392 | "ifun1", 393 | "ifun2", 394 | "ifun3", 395 | "jiajiakt", 396 | "jiangsu", 397 | "jiangxi", 398 | "jilin", 399 | "jinwenjiang", 400 | "jinyingjishi", 401 | "jinyingkatong", 402 | "jisuqiche", 403 | "kaku", 404 | "kangba", 405 | "lapse.mp4", 406 | "liaoning", 407 | "longhuadonghua", 408 | "loupe", 409 | "luxetv", 410 | "lvyou", 411 | "mandi_japan", 412 | "meilizuqiu", 413 | "meiyamovie", 414 | "mezzo", 415 | "mtvlivehd", 416 | "muzzikzz4000", 417 | "my101", 418 | "mykids", 419 | "nanfang", 420 | "natgeo", 421 | "natgeowild", 422 | "natlgeo", 423 | "nhkworldp", 424 | "ningxia", 425 | "outdoor", 426 | "qicaixiju", 427 | "qinghai", 428 | "quanjishi", 429 | "roller", 430 | "sansha", 431 | "sctv2", 432 | "sctv3", 433 | "sctv4", 434 | "sctv5", 435 | "sctv7", 436 | "sctv8", 437 | "sctv9", 438 | "sd_gonggong", 439 | "sd_nongke", 440 | "sd_qilu", 441 | "sd_shaoer", 442 | "sd_shenghuo", 443 | "sd_tiyu", 444 | "sd_yingshi", 445 | "sd_zongyi", 446 | "setxiju", 447 | "shandong", 448 | "shanghaidongfangyingshi", 449 | "shanghaijishi", 450 | "shanghaiwaiyu", 451 | "shangshixinwen", 452 | "shanxi", 453 | "shanxi_", 454 | "shenghuoshishang", 455 | "shengming", 456 | "shenzhen", 457 | "sichuan", 458 | "sport-golfplus", 459 | "sport-sports_net", 460 | "sport-trendsport", 461 | "sport_tennis", 462 | "sport_unlimited", 463 | "sport_unlimited2", 464 | "sports-golfch", 465 | "sports_net_2", 466 | "starmov", 467 | "starmovieyule", 468 | "starsports", 469 | "taiwanxiju", 470 | "tfc", 471 | "tianjin", 472 | "tlc", 473 | "traceurban", 474 | "travelchannel", 475 | "tv5monde", 476 | "tvN", 477 | "tvbfinanceinformationchannel", 478 | "viutv", 479 | "wangluoqipai", 480 | "weilaojingcai", 481 | "weixin", 482 | "wolvesvalley", 483 | "wuxingtiyu", 484 | "wxxw", 485 | "xiamen", 486 | "xindongman", 487 | "xingfucai", 488 | "xinjiang", 489 | "xizang", 490 | "xuandong", 491 | "yangguangweishi", 492 | "youman", 493 | "youxiancaijingzixun", 494 | "youxianxinwen", 495 | "youxifengyun", 496 | "yuanzhumin", 497 | "yunnan", 498 | "zgjt", 499 | "zhejiang", 500 | "zhujiang", 501 | "七彩戏剧", 502 | "三佳购物", 503 | "三沙卫视", 504 | "上海外语", 505 | "上海教育", 506 | "上海第一财经", 507 | "上海都市", 508 | "上视新闻", 509 | "世界地理", 510 | "东南卫视", 511 | "东方卫视", 512 | "东方影视", 513 | "东方财经", 514 | "东方购物", 515 | "东莞新闻综合", 516 | "东风卫视", 517 | "中华特产", 518 | "中华美食", 519 | "中国交通", 520 | "中国天气", 521 | "中国教育1台", 522 | "中国教育2台", 523 | "中国教育3台", 524 | "中国教育4台", 525 | "中天新闻台", 526 | "中学生", 527 | "中视", 528 | "中视新闻", 529 | "中视新闻台", 530 | "中视经典", 531 | "中视菁采", 532 | "中视购物", 533 | "之江记录", 534 | "乌兰察布", 535 | "乌海新闻综合", 536 | "乌海都市生活", 537 | "乐游", 538 | "书画", 539 | "云南卫视", 540 | "云南娱乐", 541 | "云南影视", 542 | "云南都市", 543 | "五星体育", 544 | "亚洲新闻", 545 | "京视剧场", 546 | "人间卫视", 547 | "优优宝贝", 548 | "优漫卡通", 549 | "优购物", 550 | "佛山公共", 551 | "佛山影视", 552 | "佛山综合", 553 | "先锋乒羽", 554 | "全纪实", 555 | "公视", 556 | "公视戏剧台", 557 | "兴安", 558 | "兵器科技", 559 | "兵团卫视", 560 | "内蒙古IPTV", 561 | "内蒙古农牧", 562 | "内蒙古卫视", 563 | "内蒙古少儿", 564 | "内蒙古文体娱乐", 565 | "内蒙古新闻综合", 566 | "内蒙古经济生活", 567 | "内蒙古蒙语卫视", 568 | "内蒙古蒙语文化", 569 | "农林卫视", 570 | "凤凰中文", 571 | "凤凰卫视中文台", 572 | "凤凰卫视电影台", 573 | "凤凰卫视资讯台", 574 | "凤凰卫视香港台", 575 | "凤凰资讯", 576 | "动漫秀场", 577 | "劲爆体育", 578 | "包头新闻综合", 579 | "包头生活服务", 580 | "包头经济频道", 581 | "北京IPTV4K", 582 | "北京体育休闲", 583 | "北京卫视", 584 | "北京影视", 585 | "北京文艺", 586 | "北京新闻", 587 | "北京生活", 588 | "北京纪实科教", 589 | "北京财经", 590 | "北京青年", 591 | "半岛新闻", 592 | "华视", 593 | "华视新闻", 594 | "华语影院", 595 | "南方卫视", 596 | "卡酷少儿", 597 | "卫生健康", 598 | "卫视中文", 599 | "卫视中文台", 600 | "厦门1", 601 | "厦门2", 602 | "厦门3", 603 | "厦门卫视", 604 | "发现之旅", 605 | "台视", 606 | "台视新闻", 607 | "台视综合", 608 | "台视财经", 609 | "吉林卫视", 610 | "呼伦贝尔", 611 | "呼伦贝尔文化旅游", 612 | "呼伦贝尔新闻综合", 613 | "呼伦贝尔生活资讯", 614 | "呼和浩特", 615 | "呼和浩特影视娱乐", 616 | "呼和浩特新闻综合", 617 | "呼和浩特都市生活", 618 | "咪咕体育", 619 | "咪咕音乐", 620 | "哈哈炫动", 621 | "哒啵电竞", 622 | "哒啵赛事", 623 | "嘉佳卡通", 624 | "四川乡村", 625 | "四川卫视", 626 | "四川妇女儿童", 627 | "四川影视文艺", 628 | "四川文化旅游", 629 | "四川新闻", 630 | "四川科教", 631 | "四川经济", 632 | "四海钓鱼", 633 | "国学", 634 | "增城电视台", 635 | "大湾区卫视", 636 | "大爱一台", 637 | "大爱电视", 638 | "天元围棋", 639 | "天津卫视", 640 | "央广购物", 641 | "央视台球", 642 | "央视高网", 643 | "女性时尚", 644 | "好享购物", 645 | "宁夏卫视", 646 | "安多卫视", 647 | "安徽公共", 648 | "安徽农业科教", 649 | "安徽卫视", 650 | "安徽国际", 651 | "安徽影视", 652 | "安徽经济生活", 653 | "安徽综艺体育", 654 | "家家购物", 655 | "家庭理财", 656 | "家有购物", 657 | "寰宇新闻", 658 | "山东体育", 659 | "山东农科", 660 | "山东卫视", 661 | "山东少儿", 662 | "山东教育", 663 | "山东文旅", 664 | "山东新闻", 665 | "山东生活", 666 | "山东综艺", 667 | "山东齐鲁", 668 | "山西卫视", 669 | "山西影视", 670 | "山西社会与法治", 671 | "山西经济", 672 | "山西黄河", 673 | "岭南戏曲", 674 | "巴彦淖尔影视娱乐", 675 | "巴彦淖尔新闻综合", 676 | "巴彦淖尔经济生活", 677 | "年代ERANewsHD", 678 | "年代MUCH", 679 | "幸福娱乐", 680 | "幸福空间居家台", 681 | "广东4K", 682 | "广东体育", 683 | "广东公共", 684 | "广东卫视", 685 | "广东嘉佳卡通", 686 | "广东少儿", 687 | "广东广电", 688 | "广东影视", 689 | "广东新闻", 690 | "广东民生", 691 | "广东珠江", 692 | "广东经济科教", 693 | "广东综艺", 694 | "广州影视", 695 | "广州新闻", 696 | "广州法治", 697 | "广州竞赛", 698 | "广州综合", 699 | "广西卫视", 700 | "康巴卫视", 701 | "延边卫视", 702 | "弈坛春秋", 703 | "影迷数位电影", 704 | "影迷电影", 705 | "影迷纪实", 706 | "快乐垂钓", 707 | "快乐购", 708 | "怀旧剧场", 709 | "成都公共", 710 | "成都影视文艺", 711 | "成都新闻综合", 712 | "成都经济资讯", 713 | "成都都市生活", 714 | "摄影", 715 | "收藏天下", 716 | "文化精品", 717 | "文物宝库", 718 | "新动漫", 719 | "新疆体育健康", 720 | "新疆卫视", 721 | "新疆少儿", 722 | "新疆汉语经济", 723 | "新疆汉语综艺", 724 | "新视觉", 725 | "无线新闻台", 726 | "无线财经台", 727 | "早期教育", 728 | "时尚购物", 729 | "明珠台", 730 | "星空卫视", 731 | "晴彩中原", 732 | "智林体育台", 733 | "杭锦旗综合", 734 | "欢笑剧场", 735 | "欢腾购物", 736 | "武术世界", 737 | "每日影院", 738 | "民视", 739 | "民视台湾台", 740 | "民视新闻台", 741 | "民视旅游台", 742 | "民视第一台", 743 | "民视综艺台", 744 | "求索动物", 745 | "求索生活", 746 | "求索科学", 747 | "求索纪录", 748 | "求索记录", 749 | "汕头经济", 750 | "汕头综合", 751 | "江苏休闲体育", 752 | "江苏优漫卡通", 753 | "江苏公共新闻", 754 | "江苏卫视", 755 | "江苏国际", 756 | "江苏城市", 757 | "江苏影视", 758 | "江苏教育电视台", 759 | "江苏综艺", 760 | "江西卫视", 761 | "江西少儿", 762 | "江西教育", 763 | "江西新闻", 764 | "江西经济生活", 765 | "汽摩", 766 | "河北卫视", 767 | "河南4K", 768 | "河南乡村", 769 | "河南公共", 770 | "河南卫视", 771 | "河南国际", 772 | "河南新闻", 773 | "河南梨园", 774 | "河南民生", 775 | "河南法治", 776 | "河南电视剧", 777 | "河南都市", 778 | "法治天地", 779 | "浙江卫视", 780 | "浙江国际", 781 | "浙江少儿", 782 | "浙江教科影视", 783 | "浙江数码时代", 784 | "浙江新闻", 785 | "浙江民生休闲", 786 | "浙江经济生活", 787 | "浦东电视台", 788 | "海南公共", 789 | "海南卫视", 790 | "海南少儿", 791 | "海南文旅", 792 | "海南经济", 793 | "海峡卫视", 794 | "海豚综合", 795 | "深圳卫视", 796 | "深圳都市", 797 | "清华", 798 | "游戏风云", 799 | "湖北卫视", 800 | "湖南卫视", 801 | "湖南国际", 802 | "湖南娱乐", 803 | "湖南教育", 804 | "湖南爱晚", 805 | "湖南电影", 806 | "湖南电视剧", 807 | "湖南经视", 808 | "湖南都市", 809 | "湖南金鹰卡通", 810 | "潮州综合", 811 | "澳亚卫视", 812 | "澳视澳门", 813 | "澳门莲花", 814 | "爱上4K", 815 | "爱尔达娱乐台", 816 | "爱看导视", 817 | "环球奇观", 818 | "环球旅游", 819 | "甘肃卫视", 820 | "生态环境", 821 | "生活时尚", 822 | "电竞.jpeg", 823 | "电竞天堂", 824 | "电视指南", 825 | "百事通", 826 | "百姓健康", 827 | "百视通", 828 | "福建公共", 829 | "福建少儿", 830 | "福建教育", 831 | "福建文体", 832 | "福建新闻", 833 | "福建旅游", 834 | "福建电视剧", 835 | "福建经济", 836 | "福建综合", 837 | "移动戏曲.PNG", 838 | "第一剧场", 839 | "精选", 840 | "纪实人文", 841 | "纯享4K", 842 | "置业频道", 843 | "翡翠台", 844 | "耀才财经", 845 | "老故事", 846 | "聚鲨环球精选", 847 | "芒果互娱", 848 | "苏州4K", 849 | "茶", 850 | "莲花卫视", 851 | "西安1", 852 | "西安丝路频道", 853 | "西安商务资讯", 854 | "西安影视频道", 855 | "西安教育", 856 | "西安新闻综合", 857 | "西安都市频道", 858 | "西藏卫视", 859 | "西藏藏语卫视", 860 | "视纳华仁纪实", 861 | "视纳华仁纪实频道", 862 | "证券服务", 863 | "财富天下", 864 | "贵州卫视", 865 | "赤峰", 866 | "赤峰影视娱乐", 867 | "赤峰新闻综合", 868 | "赤峰经济服务", 869 | "足球频道", 870 | "车迷", 871 | "辽宁卫视", 872 | "达拉特旗综合", 873 | "通辽", 874 | "通辽城市服务", 875 | "通辽新闻综合", 876 | "都市剧场", 877 | "鄂尔多斯", 878 | "鄂尔多斯新闻综合", 879 | "鄂尔多斯经济服务", 880 | "鄂尔多斯蒙语频道", 881 | "采昌影剧", 882 | "重广融媒", 883 | "重庆卫视", 884 | "重庆少儿", 885 | "重庆影视", 886 | "重庆文体娱乐", 887 | "重庆新农村", 888 | "重庆新闻", 889 | "重庆时尚生活", 890 | "重庆汽摩", 891 | "重庆社会与法", 892 | "重庆科教", 893 | "重庆移动", 894 | "金砖电视", 895 | "金色学堂", 896 | "金鹰卡通", 897 | "金鹰纪实", 898 | "钱江都市", 899 | "阿拉善", 900 | "陕西体育休闲", 901 | "陕西公共", 902 | "陕西卫视", 903 | "陕西影视", 904 | "陕西新闻资讯", 905 | "陕西生活", 906 | "陕西西部电影", 907 | "陕西都市青春", 908 | "陶瓷", 909 | "青海卫视", 910 | "靓妆", 911 | "靖天卡通", 912 | "靖天国际", 913 | "靖天戏剧", 914 | "靖天日本", 915 | "靖天日本台", 916 | "靖天映画", 917 | "靖天欢乐", 918 | "靖天电影", 919 | "靖天电影台", 920 | "靖天综合", 921 | "靖天育乐", 922 | "靖天资讯", 923 | "靖洋卡通", 924 | "靖洋戏剧", 925 | "风云剧场", 926 | "风云足球", 927 | "风云音乐", 928 | "风尚生活", 929 | "风尚购物", 930 | "香港卫视", 931 | "香港国际财经台", 932 | "高尔夫网球", 933 | "魅力足球", 934 | "黑莓动画", 935 | "黑莓电影", 936 | "黑龙江卫视", 937 | "龙华偶像", 938 | "龙华影剧", 939 | "龙华戏剧", 940 | "龙华日韩", 941 | "龙华日韩台", 942 | "龙华洋片", 943 | "龙华电影", 944 | "龙华经典", 945 | ] 946 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@esbuild/aix-ppc64@0.23.0": 6 | version "0.23.0" 7 | resolved "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz#145b74d5e4a5223489cabdc238d8dad902df5259" 8 | integrity sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ== 9 | 10 | "@esbuild/android-arm64@0.23.0": 11 | version "0.23.0" 12 | resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz#453bbe079fc8d364d4c5545069e8260228559832" 13 | integrity sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ== 14 | 15 | "@esbuild/android-arm@0.23.0": 16 | version "0.23.0" 17 | resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.23.0.tgz#26c806853aa4a4f7e683e519cd9d68e201ebcf99" 18 | integrity sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g== 19 | 20 | "@esbuild/android-x64@0.23.0": 21 | version "0.23.0" 22 | resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.23.0.tgz#1e51af9a6ac1f7143769f7ee58df5b274ed202e6" 23 | integrity sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ== 24 | 25 | "@esbuild/darwin-arm64@0.23.0": 26 | version "0.23.0" 27 | resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz#d996187a606c9534173ebd78c58098a44dd7ef9e" 28 | integrity sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow== 29 | 30 | "@esbuild/darwin-x64@0.23.0": 31 | version "0.23.0" 32 | resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz#30c8f28a7ef4e32fe46501434ebe6b0912e9e86c" 33 | integrity sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ== 34 | 35 | "@esbuild/freebsd-arm64@0.23.0": 36 | version "0.23.0" 37 | resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz#30f4fcec8167c08a6e8af9fc14b66152232e7fb4" 38 | integrity sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw== 39 | 40 | "@esbuild/freebsd-x64@0.23.0": 41 | version "0.23.0" 42 | resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz#1003a6668fe1f5d4439e6813e5b09a92981bc79d" 43 | integrity sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ== 44 | 45 | "@esbuild/linux-arm64@0.23.0": 46 | version "0.23.0" 47 | resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz#3b9a56abfb1410bb6c9138790f062587df3e6e3a" 48 | integrity sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw== 49 | 50 | "@esbuild/linux-arm@0.23.0": 51 | version "0.23.0" 52 | resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz#237a8548e3da2c48cd79ae339a588f03d1889aad" 53 | integrity sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw== 54 | 55 | "@esbuild/linux-ia32@0.23.0": 56 | version "0.23.0" 57 | resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz#4269cd19cb2de5de03a7ccfc8855dde3d284a238" 58 | integrity sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA== 59 | 60 | "@esbuild/linux-loong64@0.23.0": 61 | version "0.23.0" 62 | resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz#82b568f5658a52580827cc891cb69d2cb4f86280" 63 | integrity sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A== 64 | 65 | "@esbuild/linux-mips64el@0.23.0": 66 | version "0.23.0" 67 | resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz#9a57386c926262ae9861c929a6023ed9d43f73e5" 68 | integrity sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w== 69 | 70 | "@esbuild/linux-ppc64@0.23.0": 71 | version "0.23.0" 72 | resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz#f3a79fd636ba0c82285d227eb20ed8e31b4444f6" 73 | integrity sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw== 74 | 75 | "@esbuild/linux-riscv64@0.23.0": 76 | version "0.23.0" 77 | resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz#f9d2ef8356ce6ce140f76029680558126b74c780" 78 | integrity sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw== 79 | 80 | "@esbuild/linux-s390x@0.23.0": 81 | version "0.23.0" 82 | resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz#45390f12e802201f38a0229e216a6aed4351dfe8" 83 | integrity sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg== 84 | 85 | "@esbuild/linux-x64@0.23.0": 86 | version "0.23.0" 87 | resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz#c8409761996e3f6db29abcf9b05bee8d7d80e910" 88 | integrity sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ== 89 | 90 | "@esbuild/netbsd-x64@0.23.0": 91 | version "0.23.0" 92 | resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz#ba70db0114380d5f6cfb9003f1d378ce989cd65c" 93 | integrity sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw== 94 | 95 | "@esbuild/openbsd-arm64@0.23.0": 96 | version "0.23.0" 97 | resolved "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz#72fc55f0b189f7a882e3cf23f332370d69dfd5db" 98 | integrity sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ== 99 | 100 | "@esbuild/openbsd-x64@0.23.0": 101 | version "0.23.0" 102 | resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz#b6ae7a0911c18fe30da3db1d6d17a497a550e5d8" 103 | integrity sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg== 104 | 105 | "@esbuild/sunos-x64@0.23.0": 106 | version "0.23.0" 107 | resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz#58f0d5e55b9b21a086bfafaa29f62a3eb3470ad8" 108 | integrity sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA== 109 | 110 | "@esbuild/win32-arm64@0.23.0": 111 | version "0.23.0" 112 | resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz#b858b2432edfad62e945d5c7c9e5ddd0f528ca6d" 113 | integrity sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ== 114 | 115 | "@esbuild/win32-ia32@0.23.0": 116 | version "0.23.0" 117 | resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz#167ef6ca22a476c6c0c014a58b4f43ae4b80dec7" 118 | integrity sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA== 119 | 120 | "@esbuild/win32-x64@0.23.0": 121 | version "0.23.0" 122 | resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz#db44a6a08520b5f25bbe409f34a59f2d4bcc7ced" 123 | integrity sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g== 124 | 125 | "@isaacs/cliui@^8.0.2": 126 | version "8.0.2" 127 | resolved "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" 128 | integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== 129 | dependencies: 130 | string-width "^5.1.2" 131 | string-width-cjs "npm:string-width@^4.2.0" 132 | strip-ansi "^7.0.1" 133 | strip-ansi-cjs "npm:strip-ansi@^6.0.1" 134 | wrap-ansi "^8.1.0" 135 | wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" 136 | 137 | "@jridgewell/gen-mapping@^0.3.2": 138 | version "0.3.3" 139 | resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" 140 | integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== 141 | dependencies: 142 | "@jridgewell/set-array" "^1.0.1" 143 | "@jridgewell/sourcemap-codec" "^1.4.10" 144 | "@jridgewell/trace-mapping" "^0.3.9" 145 | 146 | "@jridgewell/resolve-uri@^3.1.0": 147 | version "3.1.1" 148 | resolved "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" 149 | integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== 150 | 151 | "@jridgewell/set-array@^1.0.1": 152 | version "1.1.2" 153 | resolved "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" 154 | integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== 155 | 156 | "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": 157 | version "1.4.15" 158 | resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" 159 | integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== 160 | 161 | "@jridgewell/trace-mapping@^0.3.9": 162 | version "0.3.20" 163 | resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" 164 | integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== 165 | dependencies: 166 | "@jridgewell/resolve-uri" "^3.1.0" 167 | "@jridgewell/sourcemap-codec" "^1.4.14" 168 | 169 | "@nodelib/fs.scandir@2.1.5": 170 | version "2.1.5" 171 | resolved "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" 172 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 173 | dependencies: 174 | "@nodelib/fs.stat" "2.0.5" 175 | run-parallel "^1.1.9" 176 | 177 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 178 | version "2.0.5" 179 | resolved "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" 180 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 181 | 182 | "@nodelib/fs.walk@^1.2.3": 183 | version "1.2.8" 184 | resolved "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" 185 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 186 | dependencies: 187 | "@nodelib/fs.scandir" "2.1.5" 188 | fastq "^1.6.0" 189 | 190 | "@pkgjs/parseargs@^0.11.0": 191 | version "0.11.0" 192 | resolved "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" 193 | integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== 194 | 195 | "@rollup/wasm-node@4.20.0": 196 | version "4.20.0" 197 | resolved "https://registry.npmmirror.com/@rollup/wasm-node/-/wasm-node-4.20.0.tgz#9888871da218e2b52a48398aab421a7bb1bf2d4a" 198 | integrity sha512-NxIRJDju9ZzXwpCZ+TMYEflT/KJPgcamVrkInPwB/jSzEIEhckHGgbC9C8Fkzt77nEZZpfF/H2BedwKfjxO9qQ== 199 | dependencies: 200 | "@types/estree" "1.0.5" 201 | optionalDependencies: 202 | fsevents "~2.3.2" 203 | 204 | "@types/accepts@*": 205 | version "1.3.7" 206 | resolved "https://registry.npmmirror.com/@types/accepts/-/accepts-1.3.7.tgz#3b98b1889d2b2386604c2bbbe62e4fb51e95b265" 207 | integrity sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ== 208 | dependencies: 209 | "@types/node" "*" 210 | 211 | "@types/body-parser@*": 212 | version "1.19.5" 213 | resolved "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" 214 | integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== 215 | dependencies: 216 | "@types/connect" "*" 217 | "@types/node" "*" 218 | 219 | "@types/connect@*": 220 | version "3.4.38" 221 | resolved "https://registry.npmmirror.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" 222 | integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== 223 | dependencies: 224 | "@types/node" "*" 225 | 226 | "@types/content-disposition@*": 227 | version "0.5.8" 228 | resolved "https://registry.npmmirror.com/@types/content-disposition/-/content-disposition-0.5.8.tgz#6742a5971f490dc41e59d277eee71361fea0b537" 229 | integrity sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg== 230 | 231 | "@types/cookies@*": 232 | version "0.7.10" 233 | resolved "https://registry.npmmirror.com/@types/cookies/-/cookies-0.7.10.tgz#c4881dca4dd913420c488508d192496c46eb4fd0" 234 | integrity sha512-hmUCjAk2fwZVPPkkPBcI7jGLIR5mg4OVoNMBwU6aVsMm/iNPY7z9/R+x2fSwLt/ZXoGua6C5Zy2k5xOo9jUyhQ== 235 | dependencies: 236 | "@types/connect" "*" 237 | "@types/express" "*" 238 | "@types/keygrip" "*" 239 | "@types/node" "*" 240 | 241 | "@types/estree@1.0.5": 242 | version "1.0.5" 243 | resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" 244 | integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== 245 | 246 | "@types/express-serve-static-core@^4.17.33": 247 | version "4.17.41" 248 | resolved "https://registry.npmmirror.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz#5077defa630c2e8d28aa9ffc2c01c157c305bef6" 249 | integrity sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA== 250 | dependencies: 251 | "@types/node" "*" 252 | "@types/qs" "*" 253 | "@types/range-parser" "*" 254 | "@types/send" "*" 255 | 256 | "@types/express@*": 257 | version "4.17.21" 258 | resolved "https://registry.npmmirror.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" 259 | integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== 260 | dependencies: 261 | "@types/body-parser" "*" 262 | "@types/express-serve-static-core" "^4.17.33" 263 | "@types/qs" "*" 264 | "@types/serve-static" "*" 265 | 266 | "@types/http-assert@*": 267 | version "1.5.5" 268 | resolved "https://registry.npmmirror.com/@types/http-assert/-/http-assert-1.5.5.tgz#dfb1063eb7c240ee3d3fe213dac5671cfb6a8dbf" 269 | integrity sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g== 270 | 271 | "@types/http-errors@*": 272 | version "2.0.4" 273 | resolved "https://registry.npmmirror.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" 274 | integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== 275 | 276 | "@types/keygrip@*": 277 | version "1.0.6" 278 | resolved "https://registry.npmmirror.com/@types/keygrip/-/keygrip-1.0.6.tgz#1749535181a2a9b02ac04a797550a8787345b740" 279 | integrity sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ== 280 | 281 | "@types/koa-compose@*": 282 | version "3.2.8" 283 | resolved "https://registry.npmmirror.com/@types/koa-compose/-/koa-compose-3.2.8.tgz#dec48de1f6b3d87f87320097686a915f1e954b57" 284 | integrity sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA== 285 | dependencies: 286 | "@types/koa" "*" 287 | 288 | "@types/koa-router@^7.4.8": 289 | version "7.4.8" 290 | resolved "https://registry.npmmirror.com/@types/koa-router/-/koa-router-7.4.8.tgz#471d0c9c20d4caa05721b50b0ae4d08c22a7cb03" 291 | integrity sha512-SkWlv4F9f+l3WqYNQHnWjYnyTxYthqt8W9az2RTdQW7Ay8bc00iRZcrb8MC75iEfPqnGcg2csEl8tTG1NQPD4A== 292 | dependencies: 293 | "@types/koa" "*" 294 | 295 | "@types/koa-send@*": 296 | version "4.1.6" 297 | resolved "https://registry.npmmirror.com/@types/koa-send/-/koa-send-4.1.6.tgz#15d90e95e3ccce669a15b6a3c56c3a650a167cea" 298 | integrity sha512-vgnNGoOJkx7FrF0Jl6rbK1f8bBecqAchKpXtKuXzqIEdXTDO6dsSTjr+eZ5m7ltSjH4K/E7auNJEQCAd0McUPA== 299 | dependencies: 300 | "@types/koa" "*" 301 | 302 | "@types/koa-static@4.0.4": 303 | version "4.0.4" 304 | resolved "https://registry.npmmirror.com/@types/koa-static/-/koa-static-4.0.4.tgz#ce6f2a5d14cc7ef19f9bf6ee8e4f3eadfcc77323" 305 | integrity sha512-j1AUzzl7eJYEk9g01hNTlhmipFh8RFbOQmaMNLvLcNNAkPw0bdTs3XTa3V045XFlrWN0QYnblbDJv2RzawTn6A== 306 | dependencies: 307 | "@types/koa" "*" 308 | "@types/koa-send" "*" 309 | 310 | "@types/koa@*": 311 | version "2.13.12" 312 | resolved "https://registry.npmmirror.com/@types/koa/-/koa-2.13.12.tgz#70d87a9061a81909e0ee11ca50168416e8d3e795" 313 | integrity sha512-vAo1KuDSYWFDB4Cs80CHvfmzSQWeUb909aQib0C0aFx4sw0K9UZFz2m5jaEP+b3X1+yr904iQiruS0hXi31jbw== 314 | dependencies: 315 | "@types/accepts" "*" 316 | "@types/content-disposition" "*" 317 | "@types/cookies" "*" 318 | "@types/http-assert" "*" 319 | "@types/http-errors" "*" 320 | "@types/keygrip" "*" 321 | "@types/koa-compose" "*" 322 | "@types/node" "*" 323 | 324 | "@types/koa@^2.15.0": 325 | version "2.15.0" 326 | resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.15.0.tgz#eca43d76f527c803b491731f95df575636e7b6f2" 327 | integrity sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g== 328 | dependencies: 329 | "@types/accepts" "*" 330 | "@types/content-disposition" "*" 331 | "@types/cookies" "*" 332 | "@types/http-assert" "*" 333 | "@types/http-errors" "*" 334 | "@types/keygrip" "*" 335 | "@types/koa-compose" "*" 336 | "@types/node" "*" 337 | 338 | "@types/linkify-it@^5": 339 | version "5.0.0" 340 | resolved "https://registry.npmmirror.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76" 341 | integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q== 342 | 343 | "@types/markdown-it@14.1.2": 344 | version "14.1.2" 345 | resolved "https://registry.npmmirror.com/@types/markdown-it/-/markdown-it-14.1.2.tgz#57f2532a0800067d9b934f3521429a2e8bfb4c61" 346 | integrity sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog== 347 | dependencies: 348 | "@types/linkify-it" "^5" 349 | "@types/mdurl" "^2" 350 | 351 | "@types/mdurl@^2": 352 | version "2.0.0" 353 | resolved "https://registry.npmmirror.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd" 354 | integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg== 355 | 356 | "@types/mime@*": 357 | version "3.0.4" 358 | resolved "https://registry.npmmirror.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" 359 | integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== 360 | 361 | "@types/mime@^1": 362 | version "1.3.5" 363 | resolved "https://registry.npmmirror.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" 364 | integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== 365 | 366 | "@types/node@*": 367 | version "20.10.5" 368 | resolved "https://registry.npmmirror.com/@types/node/-/node-20.10.5.tgz#47ad460b514096b7ed63a1dae26fad0914ed3ab2" 369 | integrity sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw== 370 | dependencies: 371 | undici-types "~5.26.4" 372 | 373 | "@types/node@22.2.0": 374 | version "22.2.0" 375 | resolved "https://registry.npmmirror.com/@types/node/-/node-22.2.0.tgz#7cf046a99f0ba4d628ad3088cb21f790df9b0c5b" 376 | integrity sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ== 377 | dependencies: 378 | undici-types "~6.13.0" 379 | 380 | "@types/opencc-js@1.0.3": 381 | version "1.0.3" 382 | resolved "https://registry.npmmirror.com/@types/opencc-js/-/opencc-js-1.0.3.tgz#8168bbdd245fc276a3ae744c114ab1fd630a4a81" 383 | integrity sha512-TENp7YkI2hNlc4dplhivSHj0hU4DORCK56VY7rniaSfA5f87uD3uv+kPIRuH9h64TGv976iVFi4gEHZZtS2y8Q== 384 | 385 | "@types/qs@*": 386 | version "6.9.10" 387 | resolved "https://registry.npmmirror.com/@types/qs/-/qs-6.9.10.tgz#0af26845b5067e1c9a622658a51f60a3934d51e8" 388 | integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== 389 | 390 | "@types/range-parser@*": 391 | version "1.2.7" 392 | resolved "https://registry.npmmirror.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" 393 | integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== 394 | 395 | "@types/send@*": 396 | version "0.17.4" 397 | resolved "https://registry.npmmirror.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" 398 | integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== 399 | dependencies: 400 | "@types/mime" "^1" 401 | "@types/node" "*" 402 | 403 | "@types/serve-static@*": 404 | version "1.15.5" 405 | resolved "https://registry.npmmirror.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" 406 | integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== 407 | dependencies: 408 | "@types/http-errors" "*" 409 | "@types/mime" "*" 410 | "@types/node" "*" 411 | 412 | abbrev@1: 413 | version "1.1.1" 414 | resolved "https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 415 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 416 | 417 | accepts@^1.3.5: 418 | version "1.3.8" 419 | resolved "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" 420 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== 421 | dependencies: 422 | mime-types "~2.1.34" 423 | negotiator "0.6.3" 424 | 425 | ansi-regex@^5.0.1: 426 | version "5.0.1" 427 | resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 428 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 429 | 430 | ansi-regex@^6.0.1: 431 | version "6.0.1" 432 | resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" 433 | integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== 434 | 435 | ansi-styles@^4.0.0: 436 | version "4.3.0" 437 | resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 438 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 439 | dependencies: 440 | color-convert "^2.0.1" 441 | 442 | ansi-styles@^6.1.0: 443 | version "6.2.1" 444 | resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" 445 | integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== 446 | 447 | any-promise@^1.0.0: 448 | version "1.3.0" 449 | resolved "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" 450 | integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== 451 | 452 | anymatch@~3.1.2: 453 | version "3.1.3" 454 | resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" 455 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 456 | dependencies: 457 | normalize-path "^3.0.0" 458 | picomatch "^2.0.4" 459 | 460 | argparse@^2.0.1: 461 | version "2.0.1" 462 | resolved "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 463 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 464 | 465 | array-union@^2.1.0: 466 | version "2.1.0" 467 | resolved "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" 468 | integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== 469 | 470 | balanced-match@^1.0.0: 471 | version "1.0.2" 472 | resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 473 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 474 | 475 | binary-extensions@^2.0.0: 476 | version "2.2.0" 477 | resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 478 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 479 | 480 | brace-expansion@^1.1.7: 481 | version "1.1.11" 482 | resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 483 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 484 | dependencies: 485 | balanced-match "^1.0.0" 486 | concat-map "0.0.1" 487 | 488 | brace-expansion@^2.0.1: 489 | version "2.0.1" 490 | resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 491 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 492 | dependencies: 493 | balanced-match "^1.0.0" 494 | 495 | braces@^3.0.2, braces@~3.0.2: 496 | version "3.0.2" 497 | resolved "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 498 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 499 | dependencies: 500 | fill-range "^7.0.1" 501 | 502 | bundle-require@^5.0.0: 503 | version "5.0.0" 504 | resolved "https://registry.npmmirror.com/bundle-require/-/bundle-require-5.0.0.tgz#071521bdea6534495cf23e92a83f889f91729e93" 505 | integrity sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w== 506 | dependencies: 507 | load-tsconfig "^0.2.3" 508 | 509 | cac@^6.7.14: 510 | version "6.7.14" 511 | resolved "https://registry.npmmirror.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" 512 | integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== 513 | 514 | cache-content-type@^1.0.0: 515 | version "1.0.1" 516 | resolved "https://registry.npmmirror.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" 517 | integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA== 518 | dependencies: 519 | mime-types "^2.1.18" 520 | ylru "^1.2.0" 521 | 522 | chokidar@^3.5.2: 523 | version "3.5.3" 524 | resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 525 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 526 | dependencies: 527 | anymatch "~3.1.2" 528 | braces "~3.0.2" 529 | glob-parent "~5.1.2" 530 | is-binary-path "~2.1.0" 531 | is-glob "~4.0.1" 532 | normalize-path "~3.0.0" 533 | readdirp "~3.6.0" 534 | optionalDependencies: 535 | fsevents "~2.3.2" 536 | 537 | chokidar@^3.6.0: 538 | version "3.6.0" 539 | resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" 540 | integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== 541 | dependencies: 542 | anymatch "~3.1.2" 543 | braces "~3.0.2" 544 | glob-parent "~5.1.2" 545 | is-binary-path "~2.1.0" 546 | is-glob "~4.0.1" 547 | normalize-path "~3.0.0" 548 | readdirp "~3.6.0" 549 | optionalDependencies: 550 | fsevents "~2.3.2" 551 | 552 | co@^4.6.0: 553 | version "4.6.0" 554 | resolved "https://registry.npmmirror.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 555 | integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== 556 | 557 | color-convert@^2.0.1: 558 | version "2.0.1" 559 | resolved "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 560 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 561 | dependencies: 562 | color-name "~1.1.4" 563 | 564 | color-name@~1.1.4: 565 | version "1.1.4" 566 | resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 567 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 568 | 569 | commander@^4.0.0: 570 | version "4.1.1" 571 | resolved "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" 572 | integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== 573 | 574 | concat-map@0.0.1: 575 | version "0.0.1" 576 | resolved "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 577 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 578 | 579 | consola@^3.2.3: 580 | version "3.2.3" 581 | resolved "https://registry.npmmirror.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" 582 | integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== 583 | 584 | content-disposition@~0.5.2: 585 | version "0.5.4" 586 | resolved "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" 587 | integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== 588 | dependencies: 589 | safe-buffer "5.2.1" 590 | 591 | content-type@^1.0.4: 592 | version "1.0.5" 593 | resolved "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" 594 | integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== 595 | 596 | cookies@~0.9.0: 597 | version "0.9.1" 598 | resolved "https://registry.npmmirror.com/cookies/-/cookies-0.9.1.tgz#3ffed6f60bb4fb5f146feeedba50acc418af67e3" 599 | integrity sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw== 600 | dependencies: 601 | depd "~2.0.0" 602 | keygrip "~1.1.0" 603 | 604 | cross-env@^7.0.3: 605 | version "7.0.3" 606 | resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" 607 | integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== 608 | dependencies: 609 | cross-spawn "^7.0.1" 610 | 611 | cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3: 612 | version "7.0.3" 613 | resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 614 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 615 | dependencies: 616 | path-key "^3.1.0" 617 | shebang-command "^2.0.0" 618 | which "^2.0.1" 619 | 620 | debug@^3.1.0: 621 | version "3.2.7" 622 | resolved "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" 623 | integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== 624 | dependencies: 625 | ms "^2.1.1" 626 | 627 | debug@^4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: 628 | version "4.3.4" 629 | resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 630 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 631 | dependencies: 632 | ms "2.1.2" 633 | 634 | debug@^4.3.5: 635 | version "4.3.6" 636 | resolved "https://registry.npmmirror.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" 637 | integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== 638 | dependencies: 639 | ms "2.1.2" 640 | 641 | deep-equal@~1.0.1: 642 | version "1.0.1" 643 | resolved "https://registry.npmmirror.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" 644 | integrity sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw== 645 | 646 | delegates@^1.0.0: 647 | version "1.0.0" 648 | resolved "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 649 | integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== 650 | 651 | depd@2.0.0, depd@^2.0.0, depd@~2.0.0: 652 | version "2.0.0" 653 | resolved "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" 654 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 655 | 656 | depd@~1.1.2: 657 | version "1.1.2" 658 | resolved "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 659 | integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== 660 | 661 | destroy@^1.0.4: 662 | version "1.2.0" 663 | resolved "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" 664 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== 665 | 666 | dir-glob@^3.0.1: 667 | version "3.0.1" 668 | resolved "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" 669 | integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== 670 | dependencies: 671 | path-type "^4.0.0" 672 | 673 | dotenv@^16.4.5: 674 | version "16.4.5" 675 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" 676 | integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== 677 | 678 | eastasianwidth@^0.2.0: 679 | version "0.2.0" 680 | resolved "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" 681 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 682 | 683 | ee-first@1.1.1: 684 | version "1.1.1" 685 | resolved "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 686 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== 687 | 688 | emoji-regex@^8.0.0: 689 | version "8.0.0" 690 | resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 691 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 692 | 693 | emoji-regex@^9.2.2: 694 | version "9.2.2" 695 | resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 696 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 697 | 698 | encodeurl@^1.0.2: 699 | version "1.0.2" 700 | resolved "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 701 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== 702 | 703 | entities@^4.4.0: 704 | version "4.5.0" 705 | resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" 706 | integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== 707 | 708 | esbuild@^0.23.0: 709 | version "0.23.0" 710 | resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.23.0.tgz#de06002d48424d9fdb7eb52dbe8e95927f852599" 711 | integrity sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA== 712 | optionalDependencies: 713 | "@esbuild/aix-ppc64" "0.23.0" 714 | "@esbuild/android-arm" "0.23.0" 715 | "@esbuild/android-arm64" "0.23.0" 716 | "@esbuild/android-x64" "0.23.0" 717 | "@esbuild/darwin-arm64" "0.23.0" 718 | "@esbuild/darwin-x64" "0.23.0" 719 | "@esbuild/freebsd-arm64" "0.23.0" 720 | "@esbuild/freebsd-x64" "0.23.0" 721 | "@esbuild/linux-arm" "0.23.0" 722 | "@esbuild/linux-arm64" "0.23.0" 723 | "@esbuild/linux-ia32" "0.23.0" 724 | "@esbuild/linux-loong64" "0.23.0" 725 | "@esbuild/linux-mips64el" "0.23.0" 726 | "@esbuild/linux-ppc64" "0.23.0" 727 | "@esbuild/linux-riscv64" "0.23.0" 728 | "@esbuild/linux-s390x" "0.23.0" 729 | "@esbuild/linux-x64" "0.23.0" 730 | "@esbuild/netbsd-x64" "0.23.0" 731 | "@esbuild/openbsd-arm64" "0.23.0" 732 | "@esbuild/openbsd-x64" "0.23.0" 733 | "@esbuild/sunos-x64" "0.23.0" 734 | "@esbuild/win32-arm64" "0.23.0" 735 | "@esbuild/win32-ia32" "0.23.0" 736 | "@esbuild/win32-x64" "0.23.0" 737 | 738 | escape-html@^1.0.3: 739 | version "1.0.3" 740 | resolved "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 741 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== 742 | 743 | execa@^5.1.1: 744 | version "5.1.1" 745 | resolved "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" 746 | integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== 747 | dependencies: 748 | cross-spawn "^7.0.3" 749 | get-stream "^6.0.0" 750 | human-signals "^2.1.0" 751 | is-stream "^2.0.0" 752 | merge-stream "^2.0.0" 753 | npm-run-path "^4.0.1" 754 | onetime "^5.1.2" 755 | signal-exit "^3.0.3" 756 | strip-final-newline "^2.0.0" 757 | 758 | fast-glob@^3.2.9: 759 | version "3.3.2" 760 | resolved "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" 761 | integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== 762 | dependencies: 763 | "@nodelib/fs.stat" "^2.0.2" 764 | "@nodelib/fs.walk" "^1.2.3" 765 | glob-parent "^5.1.2" 766 | merge2 "^1.3.0" 767 | micromatch "^4.0.4" 768 | 769 | fastq@^1.6.0: 770 | version "1.16.0" 771 | resolved "https://registry.npmmirror.com/fastq/-/fastq-1.16.0.tgz#83b9a9375692db77a822df081edb6a9cf6839320" 772 | integrity sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA== 773 | dependencies: 774 | reusify "^1.0.4" 775 | 776 | fill-range@^7.0.1: 777 | version "7.0.1" 778 | resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 779 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 780 | dependencies: 781 | to-regex-range "^5.0.1" 782 | 783 | foreground-child@^3.1.0: 784 | version "3.3.0" 785 | resolved "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" 786 | integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== 787 | dependencies: 788 | cross-spawn "^7.0.0" 789 | signal-exit "^4.0.1" 790 | 791 | fresh@~0.5.2: 792 | version "0.5.2" 793 | resolved "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 794 | integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== 795 | 796 | fsevents@~2.3.2: 797 | version "2.3.3" 798 | resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 799 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 800 | 801 | get-stream@^6.0.0: 802 | version "6.0.1" 803 | resolved "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" 804 | integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== 805 | 806 | glob-parent@^5.1.2, glob-parent@~5.1.2: 807 | version "5.1.2" 808 | resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 809 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 810 | dependencies: 811 | is-glob "^4.0.1" 812 | 813 | glob@^10.3.10: 814 | version "10.4.5" 815 | resolved "https://registry.npmmirror.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" 816 | integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== 817 | dependencies: 818 | foreground-child "^3.1.0" 819 | jackspeak "^3.1.2" 820 | minimatch "^9.0.4" 821 | minipass "^7.1.2" 822 | package-json-from-dist "^1.0.0" 823 | path-scurry "^1.11.1" 824 | 825 | globby@^11.1.0: 826 | version "11.1.0" 827 | resolved "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" 828 | integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== 829 | dependencies: 830 | array-union "^2.1.0" 831 | dir-glob "^3.0.1" 832 | fast-glob "^3.2.9" 833 | ignore "^5.2.0" 834 | merge2 "^1.4.1" 835 | slash "^3.0.0" 836 | 837 | has-flag@^3.0.0: 838 | version "3.0.0" 839 | resolved "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 840 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 841 | 842 | has-symbols@^1.0.2: 843 | version "1.0.3" 844 | resolved "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" 845 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 846 | 847 | has-tostringtag@^1.0.0: 848 | version "1.0.0" 849 | resolved "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" 850 | integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== 851 | dependencies: 852 | has-symbols "^1.0.2" 853 | 854 | http-assert@^1.3.0: 855 | version "1.5.0" 856 | resolved "https://registry.npmmirror.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f" 857 | integrity sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w== 858 | dependencies: 859 | deep-equal "~1.0.1" 860 | http-errors "~1.8.0" 861 | 862 | http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.8.0: 863 | version "1.8.1" 864 | resolved "https://registry.npmmirror.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" 865 | integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== 866 | dependencies: 867 | depd "~1.1.2" 868 | inherits "2.0.4" 869 | setprototypeof "1.2.0" 870 | statuses ">= 1.5.0 < 2" 871 | toidentifier "1.0.1" 872 | 873 | http-errors@^2.0.0: 874 | version "2.0.0" 875 | resolved "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" 876 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== 877 | dependencies: 878 | depd "2.0.0" 879 | inherits "2.0.4" 880 | setprototypeof "1.2.0" 881 | statuses "2.0.1" 882 | toidentifier "1.0.1" 883 | 884 | http-errors@~1.6.2: 885 | version "1.6.3" 886 | resolved "https://registry.npmmirror.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" 887 | integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== 888 | dependencies: 889 | depd "~1.1.2" 890 | inherits "2.0.3" 891 | setprototypeof "1.1.0" 892 | statuses ">= 1.4.0 < 2" 893 | 894 | human-signals@^2.1.0: 895 | version "2.1.0" 896 | resolved "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" 897 | integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== 898 | 899 | ignore-by-default@^1.0.1: 900 | version "1.0.1" 901 | resolved "https://registry.npmmirror.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" 902 | integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== 903 | 904 | ignore@^5.2.0: 905 | version "5.3.0" 906 | resolved "https://registry.npmmirror.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" 907 | integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== 908 | 909 | inherits@2.0.3: 910 | version "2.0.3" 911 | resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 912 | integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== 913 | 914 | inherits@2.0.4: 915 | version "2.0.4" 916 | resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 917 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 918 | 919 | is-binary-path@~2.1.0: 920 | version "2.1.0" 921 | resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 922 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 923 | dependencies: 924 | binary-extensions "^2.0.0" 925 | 926 | is-extglob@^2.1.1: 927 | version "2.1.1" 928 | resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 929 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 930 | 931 | is-fullwidth-code-point@^3.0.0: 932 | version "3.0.0" 933 | resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 934 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 935 | 936 | is-generator-function@^1.0.7: 937 | version "1.0.10" 938 | resolved "https://registry.npmmirror.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" 939 | integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== 940 | dependencies: 941 | has-tostringtag "^1.0.0" 942 | 943 | is-glob@^4.0.1, is-glob@~4.0.1: 944 | version "4.0.3" 945 | resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 946 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 947 | dependencies: 948 | is-extglob "^2.1.1" 949 | 950 | is-number@^7.0.0: 951 | version "7.0.0" 952 | resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 953 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 954 | 955 | is-stream@^2.0.0: 956 | version "2.0.1" 957 | resolved "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" 958 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 959 | 960 | isexe@^2.0.0: 961 | version "2.0.0" 962 | resolved "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 963 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 964 | 965 | jackspeak@^3.1.2: 966 | version "3.4.3" 967 | resolved "https://registry.npmmirror.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" 968 | integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== 969 | dependencies: 970 | "@isaacs/cliui" "^8.0.2" 971 | optionalDependencies: 972 | "@pkgjs/parseargs" "^0.11.0" 973 | 974 | joycon@^3.1.1: 975 | version "3.1.1" 976 | resolved "https://registry.npmmirror.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" 977 | integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== 978 | 979 | keygrip@~1.1.0: 980 | version "1.1.0" 981 | resolved "https://registry.npmmirror.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" 982 | integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== 983 | dependencies: 984 | tsscmp "1.0.6" 985 | 986 | koa-compose@^4.1.0: 987 | version "4.1.0" 988 | resolved "https://registry.npmmirror.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" 989 | integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== 990 | 991 | koa-convert@^2.0.0: 992 | version "2.0.0" 993 | resolved "https://registry.npmmirror.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5" 994 | integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA== 995 | dependencies: 996 | co "^4.6.0" 997 | koa-compose "^4.1.0" 998 | 999 | koa-router@12.0.1: 1000 | version "12.0.1" 1001 | resolved "https://registry.npmmirror.com/koa-router/-/koa-router-12.0.1.tgz#a3c1c331032d442da786f0631d23e74d51b6882e" 1002 | integrity sha512-gaDdj3GtzoLoeosacd50kBBTnnh3B9AYxDThQUo4sfUyXdOhY6ku1qyZKW88tQCRgc3Sw6ChXYXWZwwgjOxE0w== 1003 | dependencies: 1004 | debug "^4.3.4" 1005 | http-errors "^2.0.0" 1006 | koa-compose "^4.1.0" 1007 | methods "^1.1.2" 1008 | path-to-regexp "^6.2.1" 1009 | 1010 | koa-send@^5.0.0: 1011 | version "5.0.1" 1012 | resolved "https://registry.npmmirror.com/koa-send/-/koa-send-5.0.1.tgz#39dceebfafb395d0d60beaffba3a70b4f543fe79" 1013 | integrity sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ== 1014 | dependencies: 1015 | debug "^4.1.1" 1016 | http-errors "^1.7.3" 1017 | resolve-path "^1.4.0" 1018 | 1019 | koa-static@5.0.0: 1020 | version "5.0.0" 1021 | resolved "https://registry.npmmirror.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943" 1022 | integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ== 1023 | dependencies: 1024 | debug "^3.1.0" 1025 | koa-send "^5.0.0" 1026 | 1027 | koa@2.15.3: 1028 | version "2.15.3" 1029 | resolved "https://registry.npmmirror.com/koa/-/koa-2.15.3.tgz#062809266ee75ce0c75f6510a005b0e38f8c519a" 1030 | integrity sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg== 1031 | dependencies: 1032 | accepts "^1.3.5" 1033 | cache-content-type "^1.0.0" 1034 | content-disposition "~0.5.2" 1035 | content-type "^1.0.4" 1036 | cookies "~0.9.0" 1037 | debug "^4.3.2" 1038 | delegates "^1.0.0" 1039 | depd "^2.0.0" 1040 | destroy "^1.0.4" 1041 | encodeurl "^1.0.2" 1042 | escape-html "^1.0.3" 1043 | fresh "~0.5.2" 1044 | http-assert "^1.3.0" 1045 | http-errors "^1.6.3" 1046 | is-generator-function "^1.0.7" 1047 | koa-compose "^4.1.0" 1048 | koa-convert "^2.0.0" 1049 | on-finished "^2.3.0" 1050 | only "~0.0.2" 1051 | parseurl "^1.3.2" 1052 | statuses "^1.5.0" 1053 | type-is "^1.6.16" 1054 | vary "^1.1.2" 1055 | 1056 | lilconfig@^3.1.1: 1057 | version "3.1.2" 1058 | resolved "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" 1059 | integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== 1060 | 1061 | lines-and-columns@^1.1.6: 1062 | version "1.2.4" 1063 | resolved "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" 1064 | integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== 1065 | 1066 | linkify-it@^5.0.0: 1067 | version "5.0.0" 1068 | resolved "https://registry.npmmirror.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421" 1069 | integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ== 1070 | dependencies: 1071 | uc.micro "^2.0.0" 1072 | 1073 | load-tsconfig@^0.2.3: 1074 | version "0.2.5" 1075 | resolved "https://registry.npmmirror.com/load-tsconfig/-/load-tsconfig-0.2.5.tgz#453b8cd8961bfb912dea77eb6c168fe8cca3d3a1" 1076 | integrity sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg== 1077 | 1078 | lodash.sortby@^4.7.0: 1079 | version "4.7.0" 1080 | resolved "https://registry.npmmirror.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" 1081 | integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== 1082 | 1083 | lru-cache@^10.2.0: 1084 | version "10.4.3" 1085 | resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" 1086 | integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== 1087 | 1088 | lru-cache@^6.0.0: 1089 | version "6.0.0" 1090 | resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 1091 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 1092 | dependencies: 1093 | yallist "^4.0.0" 1094 | 1095 | markdown-it@14.1.0: 1096 | version "14.1.0" 1097 | resolved "https://registry.npmmirror.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45" 1098 | integrity sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg== 1099 | dependencies: 1100 | argparse "^2.0.1" 1101 | entities "^4.4.0" 1102 | linkify-it "^5.0.0" 1103 | mdurl "^2.0.0" 1104 | punycode.js "^2.3.1" 1105 | uc.micro "^2.1.0" 1106 | 1107 | mdurl@^2.0.0: 1108 | version "2.0.0" 1109 | resolved "https://registry.npmmirror.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0" 1110 | integrity sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w== 1111 | 1112 | media-typer@0.3.0: 1113 | version "0.3.0" 1114 | resolved "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 1115 | integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== 1116 | 1117 | merge-stream@^2.0.0: 1118 | version "2.0.0" 1119 | resolved "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" 1120 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 1121 | 1122 | merge2@^1.3.0, merge2@^1.4.1: 1123 | version "1.4.1" 1124 | resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" 1125 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 1126 | 1127 | methods@^1.1.2: 1128 | version "1.1.2" 1129 | resolved "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 1130 | integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== 1131 | 1132 | micromatch@^4.0.4: 1133 | version "4.0.5" 1134 | resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" 1135 | integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== 1136 | dependencies: 1137 | braces "^3.0.2" 1138 | picomatch "^2.3.1" 1139 | 1140 | mime-db@1.52.0: 1141 | version "1.52.0" 1142 | resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 1143 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 1144 | 1145 | mime-types@^2.1.18, mime-types@~2.1.24, mime-types@~2.1.34: 1146 | version "2.1.35" 1147 | resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 1148 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 1149 | dependencies: 1150 | mime-db "1.52.0" 1151 | 1152 | mimic-fn@^2.1.0: 1153 | version "2.1.0" 1154 | resolved "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 1155 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 1156 | 1157 | minimatch@^3.1.2: 1158 | version "3.1.2" 1159 | resolved "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 1160 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1161 | dependencies: 1162 | brace-expansion "^1.1.7" 1163 | 1164 | minimatch@^9.0.4: 1165 | version "9.0.5" 1166 | resolved "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" 1167 | integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== 1168 | dependencies: 1169 | brace-expansion "^2.0.1" 1170 | 1171 | "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: 1172 | version "7.1.2" 1173 | resolved "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" 1174 | integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== 1175 | 1176 | ms@2.1.2: 1177 | version "2.1.2" 1178 | resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1179 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1180 | 1181 | ms@^2.1.1: 1182 | version "2.1.3" 1183 | resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 1184 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 1185 | 1186 | mz@^2.7.0: 1187 | version "2.7.0" 1188 | resolved "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" 1189 | integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== 1190 | dependencies: 1191 | any-promise "^1.0.0" 1192 | object-assign "^4.0.1" 1193 | thenify-all "^1.0.0" 1194 | 1195 | negotiator@0.6.3: 1196 | version "0.6.3" 1197 | resolved "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" 1198 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== 1199 | 1200 | nodemon@^3.1.4: 1201 | version "3.1.4" 1202 | resolved "https://registry.npmmirror.com/nodemon/-/nodemon-3.1.4.tgz#c34dcd8eb46a05723ccde60cbdd25addcc8725e4" 1203 | integrity sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ== 1204 | dependencies: 1205 | chokidar "^3.5.2" 1206 | debug "^4" 1207 | ignore-by-default "^1.0.1" 1208 | minimatch "^3.1.2" 1209 | pstree.remy "^1.1.8" 1210 | semver "^7.5.3" 1211 | simple-update-notifier "^2.0.0" 1212 | supports-color "^5.5.0" 1213 | touch "^3.1.0" 1214 | undefsafe "^2.0.5" 1215 | 1216 | nopt@~1.0.10: 1217 | version "1.0.10" 1218 | resolved "https://registry.npmmirror.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" 1219 | integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== 1220 | dependencies: 1221 | abbrev "1" 1222 | 1223 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1224 | version "3.0.0" 1225 | resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 1226 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1227 | 1228 | npm-run-path@^4.0.1: 1229 | version "4.0.1" 1230 | resolved "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" 1231 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== 1232 | dependencies: 1233 | path-key "^3.0.0" 1234 | 1235 | object-assign@^4.0.1: 1236 | version "4.1.1" 1237 | resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1238 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 1239 | 1240 | on-finished@^2.3.0: 1241 | version "2.4.1" 1242 | resolved "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" 1243 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== 1244 | dependencies: 1245 | ee-first "1.1.1" 1246 | 1247 | onetime@^5.1.2: 1248 | version "5.1.2" 1249 | resolved "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" 1250 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 1251 | dependencies: 1252 | mimic-fn "^2.1.0" 1253 | 1254 | only@~0.0.2: 1255 | version "0.0.2" 1256 | resolved "https://registry.npmmirror.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" 1257 | integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ== 1258 | 1259 | opencc-js@1.0.5: 1260 | version "1.0.5" 1261 | resolved "https://registry.npmmirror.com/opencc-js/-/opencc-js-1.0.5.tgz#4754a9407590c5d581c9b4788acd43e8627dd464" 1262 | integrity sha512-LD+1SoNnZdlRwtYTjnQdFrSVCAaYpuDqL5CkmOaHOkKoKh7mFxUicLTRVNLU5C+Jmi1vXQ3QL4jWdgSaa4sKjg== 1263 | 1264 | package-json-from-dist@^1.0.0: 1265 | version "1.0.0" 1266 | resolved "https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" 1267 | integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== 1268 | 1269 | parseurl@^1.3.2: 1270 | version "1.3.3" 1271 | resolved "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 1272 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 1273 | 1274 | path-is-absolute@1.0.1: 1275 | version "1.0.1" 1276 | resolved "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1277 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 1278 | 1279 | path-key@^3.0.0, path-key@^3.1.0: 1280 | version "3.1.1" 1281 | resolved "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1282 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1283 | 1284 | path-scurry@^1.11.1: 1285 | version "1.11.1" 1286 | resolved "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" 1287 | integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== 1288 | dependencies: 1289 | lru-cache "^10.2.0" 1290 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 1291 | 1292 | path-to-regexp@^6.2.1: 1293 | version "6.2.1" 1294 | resolved "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" 1295 | integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== 1296 | 1297 | path-type@^4.0.0: 1298 | version "4.0.0" 1299 | resolved "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" 1300 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 1301 | 1302 | picocolors@^1.0.1: 1303 | version "1.0.1" 1304 | resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" 1305 | integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== 1306 | 1307 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: 1308 | version "2.3.1" 1309 | resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1310 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1311 | 1312 | pirates@^4.0.1: 1313 | version "4.0.6" 1314 | resolved "https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" 1315 | integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== 1316 | 1317 | postcss-load-config@^6.0.1: 1318 | version "6.0.1" 1319 | resolved "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-6.0.1.tgz#6fd7dcd8ae89badcf1b2d644489cbabf83aa8096" 1320 | integrity sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g== 1321 | dependencies: 1322 | lilconfig "^3.1.1" 1323 | 1324 | pstree.remy@^1.1.8: 1325 | version "1.1.8" 1326 | resolved "https://registry.npmmirror.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" 1327 | integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== 1328 | 1329 | punycode.js@^2.3.1: 1330 | version "2.3.1" 1331 | resolved "https://registry.npmmirror.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7" 1332 | integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA== 1333 | 1334 | punycode@^2.1.0: 1335 | version "2.3.1" 1336 | resolved "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" 1337 | integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== 1338 | 1339 | queue-microtask@^1.2.2: 1340 | version "1.2.3" 1341 | resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 1342 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 1343 | 1344 | readdirp@~3.6.0: 1345 | version "3.6.0" 1346 | resolved "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 1347 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1348 | dependencies: 1349 | picomatch "^2.2.1" 1350 | 1351 | resolve-from@^5.0.0: 1352 | version "5.0.0" 1353 | resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" 1354 | integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== 1355 | 1356 | resolve-path@^1.4.0: 1357 | version "1.4.0" 1358 | resolved "https://registry.npmmirror.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" 1359 | integrity sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w== 1360 | dependencies: 1361 | http-errors "~1.6.2" 1362 | path-is-absolute "1.0.1" 1363 | 1364 | reusify@^1.0.4: 1365 | version "1.0.4" 1366 | resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 1367 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 1368 | 1369 | rollup@^4.19.0, "rollup@npm:@rollup/wasm-node": 1370 | version "4.9.1" 1371 | resolved "https://registry.npmmirror.com/@rollup/wasm-node/-/wasm-node-4.9.1.tgz#11144d4df1a077a652c6f9723587e8479845d8ab" 1372 | integrity sha512-awrdTJgcUC0IA5X7Zi2HJlCcdhxaSDZHaBhoNuKt+TgDPdLatbw8GKKcLpqKVEAIOwfajNCQP+taQ/EgM+090A== 1373 | optionalDependencies: 1374 | fsevents "~2.3.2" 1375 | 1376 | run-parallel@^1.1.9: 1377 | version "1.2.0" 1378 | resolved "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 1379 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 1380 | dependencies: 1381 | queue-microtask "^1.2.2" 1382 | 1383 | safe-buffer@5.2.1: 1384 | version "5.2.1" 1385 | resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1386 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1387 | 1388 | semver@^7.5.3: 1389 | version "7.5.4" 1390 | resolved "https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" 1391 | integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== 1392 | dependencies: 1393 | lru-cache "^6.0.0" 1394 | 1395 | setprototypeof@1.1.0: 1396 | version "1.1.0" 1397 | resolved "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 1398 | integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== 1399 | 1400 | setprototypeof@1.2.0: 1401 | version "1.2.0" 1402 | resolved "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" 1403 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== 1404 | 1405 | shebang-command@^2.0.0: 1406 | version "2.0.0" 1407 | resolved "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1408 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1409 | dependencies: 1410 | shebang-regex "^3.0.0" 1411 | 1412 | shebang-regex@^3.0.0: 1413 | version "3.0.0" 1414 | resolved "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1415 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1416 | 1417 | signal-exit@^3.0.3: 1418 | version "3.0.7" 1419 | resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 1420 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 1421 | 1422 | signal-exit@^4.0.1: 1423 | version "4.1.0" 1424 | resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" 1425 | integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== 1426 | 1427 | simple-update-notifier@^2.0.0: 1428 | version "2.0.0" 1429 | resolved "https://registry.npmmirror.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" 1430 | integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== 1431 | dependencies: 1432 | semver "^7.5.3" 1433 | 1434 | slash@^3.0.0: 1435 | version "3.0.0" 1436 | resolved "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" 1437 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== 1438 | 1439 | source-map@0.8.0-beta.0: 1440 | version "0.8.0-beta.0" 1441 | resolved "https://registry.npmmirror.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" 1442 | integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== 1443 | dependencies: 1444 | whatwg-url "^7.0.0" 1445 | 1446 | statuses@2.0.1: 1447 | version "2.0.1" 1448 | resolved "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" 1449 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== 1450 | 1451 | "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0: 1452 | version "1.5.0" 1453 | resolved "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 1454 | integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== 1455 | 1456 | "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: 1457 | name string-width-cjs 1458 | version "4.2.3" 1459 | resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1460 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1461 | dependencies: 1462 | emoji-regex "^8.0.0" 1463 | is-fullwidth-code-point "^3.0.0" 1464 | strip-ansi "^6.0.1" 1465 | 1466 | string-width@^5.0.1, string-width@^5.1.2: 1467 | version "5.1.2" 1468 | resolved "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" 1469 | integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== 1470 | dependencies: 1471 | eastasianwidth "^0.2.0" 1472 | emoji-regex "^9.2.2" 1473 | strip-ansi "^7.0.1" 1474 | 1475 | "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1476 | name strip-ansi-cjs 1477 | version "6.0.1" 1478 | resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1479 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1480 | dependencies: 1481 | ansi-regex "^5.0.1" 1482 | 1483 | strip-ansi@^7.0.1: 1484 | version "7.1.0" 1485 | resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" 1486 | integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== 1487 | dependencies: 1488 | ansi-regex "^6.0.1" 1489 | 1490 | strip-final-newline@^2.0.0: 1491 | version "2.0.0" 1492 | resolved "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" 1493 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== 1494 | 1495 | sucrase@^3.35.0: 1496 | version "3.35.0" 1497 | resolved "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" 1498 | integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== 1499 | dependencies: 1500 | "@jridgewell/gen-mapping" "^0.3.2" 1501 | commander "^4.0.0" 1502 | glob "^10.3.10" 1503 | lines-and-columns "^1.1.6" 1504 | mz "^2.7.0" 1505 | pirates "^4.0.1" 1506 | ts-interface-checker "^0.1.9" 1507 | 1508 | supports-color@^5.5.0: 1509 | version "5.5.0" 1510 | resolved "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1511 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1512 | dependencies: 1513 | has-flag "^3.0.0" 1514 | 1515 | thenify-all@^1.0.0: 1516 | version "1.6.0" 1517 | resolved "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" 1518 | integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== 1519 | dependencies: 1520 | thenify ">= 3.1.0 < 4" 1521 | 1522 | "thenify@>= 3.1.0 < 4": 1523 | version "3.3.1" 1524 | resolved "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" 1525 | integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== 1526 | dependencies: 1527 | any-promise "^1.0.0" 1528 | 1529 | to-regex-range@^5.0.1: 1530 | version "5.0.1" 1531 | resolved "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1532 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1533 | dependencies: 1534 | is-number "^7.0.0" 1535 | 1536 | toidentifier@1.0.1: 1537 | version "1.0.1" 1538 | resolved "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" 1539 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== 1540 | 1541 | touch@^3.1.0: 1542 | version "3.1.0" 1543 | resolved "https://registry.npmmirror.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" 1544 | integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== 1545 | dependencies: 1546 | nopt "~1.0.10" 1547 | 1548 | tr46@^1.0.1: 1549 | version "1.0.1" 1550 | resolved "https://registry.npmmirror.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" 1551 | integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== 1552 | dependencies: 1553 | punycode "^2.1.0" 1554 | 1555 | tree-kill@^1.2.2: 1556 | version "1.2.2" 1557 | resolved "https://registry.npmmirror.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" 1558 | integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== 1559 | 1560 | ts-interface-checker@^0.1.9: 1561 | version "0.1.13" 1562 | resolved "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" 1563 | integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== 1564 | 1565 | tsscmp@1.0.6: 1566 | version "1.0.6" 1567 | resolved "https://registry.npmmirror.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" 1568 | integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== 1569 | 1570 | tsup@8.2.4: 1571 | version "8.2.4" 1572 | resolved "https://registry.npmmirror.com/tsup/-/tsup-8.2.4.tgz#5e31790c1e66392cee384ad746ed51c106614beb" 1573 | integrity sha512-akpCPePnBnC/CXgRrcy72ZSntgIEUa1jN0oJbbvpALWKNOz1B7aM+UVDWGRGIO/T/PZugAESWDJUAb5FD48o8Q== 1574 | dependencies: 1575 | bundle-require "^5.0.0" 1576 | cac "^6.7.14" 1577 | chokidar "^3.6.0" 1578 | consola "^3.2.3" 1579 | debug "^4.3.5" 1580 | esbuild "^0.23.0" 1581 | execa "^5.1.1" 1582 | globby "^11.1.0" 1583 | joycon "^3.1.1" 1584 | picocolors "^1.0.1" 1585 | postcss-load-config "^6.0.1" 1586 | resolve-from "^5.0.0" 1587 | rollup "^4.19.0" 1588 | source-map "0.8.0-beta.0" 1589 | sucrase "^3.35.0" 1590 | tree-kill "^1.2.2" 1591 | 1592 | type-is@^1.6.16: 1593 | version "1.6.18" 1594 | resolved "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 1595 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== 1596 | dependencies: 1597 | media-typer "0.3.0" 1598 | mime-types "~2.1.24" 1599 | 1600 | typescript@5.5.4: 1601 | version "5.5.4" 1602 | resolved "https://registry.npmmirror.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" 1603 | integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== 1604 | 1605 | uc.micro@^2.0.0: 1606 | version "2.0.0" 1607 | resolved "https://registry.npmmirror.com/uc.micro/-/uc.micro-2.0.0.tgz#84b3c335c12b1497fd9e80fcd3bfa7634c363ff1" 1608 | integrity sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig== 1609 | 1610 | uc.micro@^2.1.0: 1611 | version "2.1.0" 1612 | resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee" 1613 | integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A== 1614 | 1615 | undefsafe@^2.0.5: 1616 | version "2.0.5" 1617 | resolved "https://registry.npmmirror.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" 1618 | integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== 1619 | 1620 | undici-types@~5.26.4: 1621 | version "5.26.5" 1622 | resolved "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" 1623 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== 1624 | 1625 | undici-types@~6.13.0: 1626 | version "6.13.0" 1627 | resolved "https://registry.npmmirror.com/undici-types/-/undici-types-6.13.0.tgz#e3e79220ab8c81ed1496b5812471afd7cf075ea5" 1628 | integrity sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg== 1629 | 1630 | vary@^1.1.2: 1631 | version "1.1.2" 1632 | resolved "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 1633 | integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== 1634 | 1635 | webidl-conversions@^4.0.2: 1636 | version "4.0.2" 1637 | resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" 1638 | integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== 1639 | 1640 | whatwg-url@^7.0.0: 1641 | version "7.1.0" 1642 | resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" 1643 | integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== 1644 | dependencies: 1645 | lodash.sortby "^4.7.0" 1646 | tr46 "^1.0.1" 1647 | webidl-conversions "^4.0.2" 1648 | 1649 | which@^2.0.1: 1650 | version "2.0.2" 1651 | resolved "https://registry.npmmirror.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1652 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1653 | dependencies: 1654 | isexe "^2.0.0" 1655 | 1656 | "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": 1657 | version "7.0.0" 1658 | resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1659 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1660 | dependencies: 1661 | ansi-styles "^4.0.0" 1662 | string-width "^4.1.0" 1663 | strip-ansi "^6.0.0" 1664 | 1665 | wrap-ansi@^8.1.0: 1666 | version "8.1.0" 1667 | resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" 1668 | integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== 1669 | dependencies: 1670 | ansi-styles "^6.1.0" 1671 | string-width "^5.0.1" 1672 | strip-ansi "^7.0.1" 1673 | 1674 | yallist@^4.0.0: 1675 | version "4.0.0" 1676 | resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1677 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1678 | 1679 | ylru@^1.2.0: 1680 | version "1.3.2" 1681 | resolved "https://registry.npmmirror.com/ylru/-/ylru-1.3.2.tgz#0de48017473275a4cbdfc83a1eaf67c01af8a785" 1682 | integrity sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA== 1683 | --------------------------------------------------------------------------------