Lint the project with antfu/eslint-config and remove Prettier. (#26)

This commit is contained in:
Alessandro Jean 2023-09-08 15:20:45 -03:00 committed by GitHub
parent 6df2b8ee5a
commit 954749a08f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 1118 additions and 535 deletions

View File

@ -1,31 +1,21 @@
module.exports = { module.exports = {
root: true, root: true,
env: { extends: ["@antfu"],
browser: true,
es2021: true,
node: true,
"vue/setup-compiler-macros": true,
},
parser: "vue-eslint-parser",
extends: [
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"standard",
],
parserOptions: {
ecmaVersion: "latest",
parser: "@typescript-eslint/parser",
sourceType: "module",
},
plugins: [
"vue",
"@typescript-eslint",
],
rules: { rules: {
"comma-dangle": ["error", "only-multiline"], "comma-dangle": ["error", "only-multiline"],
quotes: ["error", "double"], "quotes": "off",
indent: ["error", "tab"], "no-tabs": "off",
"no-tabs": 0, "arrow-parens": ["error", "always"],
"@typescript-eslint/quotes": ["error", "double", { avoidEscape: true }],
"indent": "off",
"semi": ["error", "never"],
"@typescript-eslint/indent": ["error", "tab"],
"@typescript-eslint/brace-style": ["error", "1tbs"],
"@typescript-eslint/semi": ["error", "never"],
"vue/no-extra-parens": "off",
"vue/html-indent": ["error", "tab"],
"curly": ["error", "all"],
"brace-style": ["error", "1tbs"],
"no-console": "off", "no-console": "off",
"no-debugger": "off", "no-debugger": "off",
"vue/multi-word-component-names": "off", "vue/multi-word-component-names": "off",

3
website/.npmrc Normal file
View File

@ -0,0 +1,3 @@
public-hoist-pattern[]=*eslint-plugin-*
public-hoist-pattern[]=@typescript-eslint/eslint-plugin
public-hoist-pattern[]=@antfu/*

View File

@ -1,18 +0,0 @@
*.png
*.jpg
*.webm
*.webp
*.ico
*.svg
*.md
*.styl
*.vue
*.xml
*.otf
dist
pnpm-lock.yaml
cache
template
temp
!CHANGELOG.md
.temp

View File

@ -1,9 +0,0 @@
export default {
tabWidth: 4,
useTabs: true,
printWidth: 120,
trailingComma: "es5",
bracketSpacing: true,
htmlWhitespaceSensitivity: "ignore",
endOfLine: "auto",
}

View File

@ -22,17 +22,16 @@
"dev": "vitepress dev src", "dev": "vitepress dev src",
"build": "vitepress build src", "build": "vitepress build src",
"preview": "vitepress preview src", "preview": "vitepress preview src",
"lint": "pnpm lint:es && pnpm lint:prettier && pnpm lint:mdl && pnpm lint:style", "lint": "pnpm lint:es && pnpm lint:mdl && pnpm lint:style",
"lint:fix": "pnpm lint:es:fix && pnpm lint:prettier:fix && pnpm lint:style:fix", "lint:fix": "pnpm lint:es:fix && pnpm lint:prettier:fix && pnpm lint:style:fix",
"lint:es": "eslint . --ext .vue,.js,.ts,.cjs,.mjs,.jsx,.tsx", "lint:es": "eslint . --ext .vue,.js,.ts,.cjs,.mjs,.jsx,.tsx",
"lint:es:fix": "eslint . --ext .vue,.js,.ts,.cjs,.mjs,.jsx,.tsx --fix", "lint:es:fix": "eslint . --ext .vue,.js,.ts,.cjs,.mjs,.jsx,.tsx --fix",
"lint:prettier": "prettier --check \"src/**/*\"",
"lint:prettier:fix": "prettier --check --write \"src/**/*\"",
"lint:mdl": "markdownlint \"**/*.md\" \".github/**/*.md\" --enable sentences-per-line --disable MD025 MD033", "lint:mdl": "markdownlint \"**/*.md\" \".github/**/*.md\" --enable sentences-per-line --disable MD025 MD033",
"lint:style": "stylelint \"**/*.{styl,vue}\" \"src/.vitepress/**/*.{styl,vue}\"", "lint:style": "stylelint \"**/*.{styl,vue}\" \"src/.vitepress/**/*.{styl,vue}\"",
"lint:style:fix": "stylelint --fix \"**/*.{styl,vue}\" \"src/.vitepress/**/*.{styl,vue}\"" "lint:style:fix": "stylelint --fix \"**/*.{styl,vue}\" \"src/.vitepress/**/*.{styl,vue}\""
}, },
"devDependencies": { "devDependencies": {
"@antfu/eslint-config": "^0.41.0",
"@mdit/plugin-attrs": "^0.4.8", "@mdit/plugin-attrs": "^0.4.8",
"@mdit/plugin-figure": "^0.4.8", "@mdit/plugin-figure": "^0.4.8",
"@mdit/plugin-img-lazyload": "^0.4.8", "@mdit/plugin-img-lazyload": "^0.4.8",
@ -52,7 +51,6 @@
"lint-staged": "^14.0.1", "lint-staged": "^14.0.1",
"markdownlint": "^0.30.0", "markdownlint": "^0.30.0",
"markdownlint-cli": "^0.35.0", "markdownlint-cli": "^0.35.0",
"prettier": "^3.0.3",
"sentences-per-line": "^0.2.1", "sentences-per-line": "^0.2.1",
"stylelint": "^15.10.3", "stylelint": "^15.10.3",
"stylelint-stylus": "^0.18.0", "stylelint-stylus": "^0.18.0",

View File

@ -33,6 +33,9 @@ dependencies:
version: 2.29.4 version: 2.29.4
devDependencies: devDependencies:
'@antfu/eslint-config':
specifier: ^0.41.0
version: 0.41.0(eslint@8.48.0)(typescript@5.2.2)
'@mdit/plugin-attrs': '@mdit/plugin-attrs':
specifier: ^0.4.8 specifier: ^0.4.8
version: 0.4.8 version: 0.4.8
@ -90,9 +93,6 @@ devDependencies:
markdownlint-cli: markdownlint-cli:
specifier: ^0.35.0 specifier: ^0.35.0
version: 0.35.0 version: 0.35.0
prettier:
specifier: ^3.0.3
version: 3.0.3
sentences-per-line: sentences-per-line:
specifier: ^0.2.1 specifier: ^0.2.1
version: 0.2.1 version: 0.2.1
@ -272,6 +272,102 @@ packages:
'@algolia/requester-common': 4.19.1 '@algolia/requester-common': 4.19.1
dev: true dev: true
/@antfu/eslint-config-basic@0.41.0(@typescript-eslint/eslint-plugin@6.5.0)(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2):
resolution: {integrity: sha512-zcwFv+nEV/NroeeVWriNdnIGd9soOLRG8wIiVz4VVJ0BjONrqQR56HLG/gDxH/1GUYBnQCEcVxGUmegce08cnw==}
peerDependencies:
eslint: '>=7.4.0'
dependencies:
eslint: 8.48.0
eslint-plugin-antfu: 0.41.0(eslint@8.48.0)(typescript@5.2.2)
eslint-plugin-eslint-comments: 3.2.0(eslint@8.48.0)
eslint-plugin-html: 7.1.0
eslint-plugin-import: /eslint-plugin-i@2.28.0-2(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)
eslint-plugin-jsonc: 2.9.0(eslint@8.48.0)
eslint-plugin-markdown: 3.0.1(eslint@8.48.0)
eslint-plugin-n: 16.0.2(eslint@8.48.0)
eslint-plugin-no-only-tests: 3.1.0
eslint-plugin-promise: 6.1.1(eslint@8.48.0)
eslint-plugin-unicorn: 48.0.1(eslint@8.48.0)
eslint-plugin-unused-imports: 3.0.0(@typescript-eslint/eslint-plugin@6.5.0)(eslint@8.48.0)
eslint-plugin-yml: 1.8.0(eslint@8.48.0)
jsonc-eslint-parser: 2.3.0
yaml-eslint-parser: 1.2.2
transitivePeerDependencies:
- '@typescript-eslint/eslint-plugin'
- '@typescript-eslint/parser'
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
- typescript
dev: true
/@antfu/eslint-config-ts@0.41.0(eslint@8.48.0)(typescript@5.2.2):
resolution: {integrity: sha512-ng3GYpJGZgrxGwBVda/MgUpveH3LbEqdPCFi1+S5e62W4kf8rmEVbhc0I8w7/aKN0uNqir5SInYg8gob2maDAQ==}
peerDependencies:
eslint: '>=7.4.0'
typescript: '>=3.9'
dependencies:
'@antfu/eslint-config-basic': 0.41.0(@typescript-eslint/eslint-plugin@6.5.0)(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2)
'@typescript-eslint/eslint-plugin': 6.5.0(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2)
'@typescript-eslint/parser': 6.5.0(eslint@8.48.0)(typescript@5.2.2)
eslint: 8.48.0
eslint-plugin-jest: 27.2.3(@typescript-eslint/eslint-plugin@6.5.0)(eslint@8.48.0)(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- jest
- supports-color
dev: true
/@antfu/eslint-config-vue@0.41.0(@typescript-eslint/eslint-plugin@6.5.0)(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2):
resolution: {integrity: sha512-iJiEGRUgRmT3mQCmGl0hTMwq/ShXRjRPjpgsDcphKJyEF06ZIR/4gxHn+utQRLT2hD39DQN8gk0ZbpV3gWtf/g==}
peerDependencies:
eslint: '>=7.4.0'
dependencies:
'@antfu/eslint-config-basic': 0.41.0(@typescript-eslint/eslint-plugin@6.5.0)(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2)
'@antfu/eslint-config-ts': 0.41.0(eslint@8.48.0)(typescript@5.2.2)
eslint: 8.48.0
eslint-plugin-vue: 9.17.0(eslint@8.48.0)
local-pkg: 0.4.3
transitivePeerDependencies:
- '@typescript-eslint/eslint-plugin'
- '@typescript-eslint/parser'
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- jest
- supports-color
- typescript
dev: true
/@antfu/eslint-config@0.41.0(eslint@8.48.0)(typescript@5.2.2):
resolution: {integrity: sha512-510DginDPdzf45O6HOah3cK6NHXxobBc43IdBQCQmUGb+av9LIJjrd1idThFoyFh6m05iZ4YX/mhnhhJFqLiNw==}
peerDependencies:
eslint: '>=7.4.0'
dependencies:
'@antfu/eslint-config-vue': 0.41.0(@typescript-eslint/eslint-plugin@6.5.0)(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2)
'@typescript-eslint/eslint-plugin': 6.5.0(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2)
'@typescript-eslint/parser': 6.5.0(eslint@8.48.0)(typescript@5.2.2)
eslint: 8.48.0
eslint-plugin-eslint-comments: 3.2.0(eslint@8.48.0)
eslint-plugin-html: 7.1.0
eslint-plugin-import: /eslint-plugin-i@2.28.0-2(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)
eslint-plugin-jsonc: 2.9.0(eslint@8.48.0)
eslint-plugin-n: 16.0.2(eslint@8.48.0)
eslint-plugin-promise: 6.1.1(eslint@8.48.0)
eslint-plugin-unicorn: 48.0.1(eslint@8.48.0)
eslint-plugin-vue: 9.17.0(eslint@8.48.0)
eslint-plugin-yml: 1.8.0(eslint@8.48.0)
jsonc-eslint-parser: 2.3.0
yaml-eslint-parser: 1.2.2
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- jest
- supports-color
- typescript
dev: true
/@babel/code-frame@7.22.13: /@babel/code-frame@7.22.13:
resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -1118,6 +1214,12 @@ packages:
'@types/mdurl': 1.0.2 '@types/mdurl': 1.0.2
dev: true dev: true
/@types/mdast@3.0.12:
resolution: {integrity: sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==}
dependencies:
'@types/unist': 2.0.8
dev: true
/@types/mdurl@1.0.2: /@types/mdurl@1.0.2:
resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==}
dev: true dev: true
@ -1138,6 +1240,10 @@ packages:
resolution: {integrity: sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==} resolution: {integrity: sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==}
dev: true dev: true
/@types/unist@2.0.8:
resolution: {integrity: sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==}
dev: true
/@types/web-bluetooth@0.0.16: /@types/web-bluetooth@0.0.16:
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
dev: false dev: false
@ -1196,6 +1302,14 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/scope-manager@5.62.0:
resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/visitor-keys': 5.62.0
dev: true
/@typescript-eslint/scope-manager@6.5.0: /@typescript-eslint/scope-manager@6.5.0:
resolution: {integrity: sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==} resolution: {integrity: sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
@ -1224,11 +1338,37 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/types@5.62.0:
resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/@typescript-eslint/types@6.5.0: /@typescript-eslint/types@6.5.0:
resolution: {integrity: sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==} resolution: {integrity: sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
dev: true dev: true
/@typescript-eslint/typescript-estree@5.62.0(typescript@5.2.2):
resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/visitor-keys': 5.62.0
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
semver: 7.5.4
tsutils: 3.21.0(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/typescript-estree@6.5.0(typescript@5.2.2): /@typescript-eslint/typescript-estree@6.5.0(typescript@5.2.2):
resolution: {integrity: sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==} resolution: {integrity: sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
@ -1250,6 +1390,26 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/utils@5.62.0(eslint@8.48.0)(typescript@5.2.2):
resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0)
'@types/json-schema': 7.0.12
'@types/semver': 7.5.1
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2)
eslint: 8.48.0
eslint-scope: 5.1.1
semver: 7.5.4
transitivePeerDependencies:
- supports-color
- typescript
dev: true
/@typescript-eslint/utils@6.5.0(eslint@8.48.0)(typescript@5.2.2): /@typescript-eslint/utils@6.5.0(eslint@8.48.0)(typescript@5.2.2):
resolution: {integrity: sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==} resolution: {integrity: sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
@ -1269,6 +1429,14 @@ packages:
- typescript - typescript
dev: true dev: true
/@typescript-eslint/visitor-keys@5.62.0:
resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
'@typescript-eslint/types': 5.62.0
eslint-visitor-keys: 3.4.3
dev: true
/@typescript-eslint/visitor-keys@6.5.0: /@typescript-eslint/visitor-keys@6.5.0:
resolution: {integrity: sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==} resolution: {integrity: sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
@ -1743,6 +1911,11 @@ packages:
fill-range: 7.0.1 fill-range: 7.0.1
dev: true dev: true
/builtin-modules@3.3.0:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
engines: {node: '>=6'}
dev: true
/builtins@5.0.1: /builtins@5.0.1:
resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==}
dependencies: dependencies:
@ -1807,6 +1980,18 @@ packages:
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
dev: true dev: true
/character-entities-legacy@1.1.4:
resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==}
dev: true
/character-entities@1.2.4:
resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==}
dev: true
/character-reference-invalid@1.1.4:
resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
dev: true
/chokidar@3.5.3: /chokidar@3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
engines: {node: '>= 8.10.0'} engines: {node: '>= 8.10.0'}
@ -1822,6 +2007,18 @@ packages:
fsevents: 2.3.3 fsevents: 2.3.3
dev: true dev: true
/ci-info@3.8.0:
resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==}
engines: {node: '>=8'}
dev: true
/clean-regexp@1.0.0:
resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==}
engines: {node: '>=4'}
dependencies:
escape-string-regexp: 1.0.5
dev: true
/cli-cursor@4.0.0: /cli-cursor@4.0.0:
resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@ -2355,6 +2552,16 @@ packages:
- supports-color - supports-color
dev: true dev: true
/eslint-plugin-antfu@0.41.0(eslint@8.48.0)(typescript@5.2.2):
resolution: {integrity: sha512-JeEeDZgz7oqYPYWYNQHdXrKaW2nhJz/70jeMZUkaNjVp72cpsJPH3idiEhIhGu3wjFdsOMCoEkboT/DQXlCaqA==}
dependencies:
'@typescript-eslint/utils': 6.5.0(eslint@8.48.0)(typescript@5.2.2)
transitivePeerDependencies:
- eslint
- supports-color
- typescript
dev: true
/eslint-plugin-es-x@7.2.0(eslint@8.48.0): /eslint-plugin-es-x@7.2.0(eslint@8.48.0):
resolution: {integrity: sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==} resolution: {integrity: sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
@ -2366,6 +2573,46 @@ packages:
eslint: 8.48.0 eslint: 8.48.0
dev: true dev: true
/eslint-plugin-eslint-comments@3.2.0(eslint@8.48.0):
resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==}
engines: {node: '>=6.5.0'}
peerDependencies:
eslint: '>=4.19.1'
dependencies:
escape-string-regexp: 1.0.5
eslint: 8.48.0
ignore: 5.2.4
dev: true
/eslint-plugin-html@7.1.0:
resolution: {integrity: sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==}
dependencies:
htmlparser2: 8.0.2
dev: true
/eslint-plugin-i@2.28.0-2(@typescript-eslint/parser@6.5.0)(eslint@8.48.0):
resolution: {integrity: sha512-z48kG4qmE4TmiLcxbmvxMT5ycwvPkXaWW0XpU1L768uZaTbiDbxsHMEdV24JHlOR1xDsPpKW39BfP/pRdYIwFA==}
engines: {node: '>=12'}
peerDependencies:
eslint: ^7.2.0 || ^8
dependencies:
debug: 3.2.7
doctrine: 2.1.0
eslint: 8.48.0
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.5.0)(eslint-import-resolver-node@0.3.9)(eslint@8.48.0)
get-tsconfig: 4.7.0
is-glob: 4.0.3
minimatch: 3.1.2
resolve: 1.22.4
semver: 7.5.4
transitivePeerDependencies:
- '@typescript-eslint/parser'
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
dev: true
/eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.5.0)(eslint@8.48.0): /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.5.0)(eslint@8.48.0):
resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==} resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -2401,6 +2648,51 @@ packages:
- supports-color - supports-color
dev: true dev: true
/eslint-plugin-jest@27.2.3(@typescript-eslint/eslint-plugin@6.5.0)(eslint@8.48.0)(typescript@5.2.2):
resolution: {integrity: sha512-sRLlSCpICzWuje66Gl9zvdF6mwD5X86I4u55hJyFBsxYOsBCmT5+kSUjf+fkFWVMMgpzNEupjW8WzUqi83hJAQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@typescript-eslint/eslint-plugin': ^5.0.0 || ^6.0.0
eslint: ^7.0.0 || ^8.0.0
jest: '*'
peerDependenciesMeta:
'@typescript-eslint/eslint-plugin':
optional: true
jest:
optional: true
dependencies:
'@typescript-eslint/eslint-plugin': 6.5.0(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2)
'@typescript-eslint/utils': 5.62.0(eslint@8.48.0)(typescript@5.2.2)
eslint: 8.48.0
transitivePeerDependencies:
- supports-color
- typescript
dev: true
/eslint-plugin-jsonc@2.9.0(eslint@8.48.0):
resolution: {integrity: sha512-RK+LeONVukbLwT2+t7/OY54NJRccTXh/QbnXzPuTLpFMVZhPuq1C9E07+qWenGx7rrQl0kAalAWl7EmB+RjpGA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: '>=6.0.0'
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0)
eslint: 8.48.0
jsonc-eslint-parser: 2.3.0
natural-compare: 1.4.0
dev: true
/eslint-plugin-markdown@3.0.1(eslint@8.48.0):
resolution: {integrity: sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
eslint: 8.48.0
mdast-util-from-markdown: 0.8.5
transitivePeerDependencies:
- supports-color
dev: true
/eslint-plugin-n@16.0.2(eslint@8.48.0): /eslint-plugin-n@16.0.2(eslint@8.48.0):
resolution: {integrity: sha512-Y66uDfUNbBzypsr0kELWrIz+5skicECrLUqlWuXawNSLUq3ltGlCwu6phboYYOTSnoTdHgTLrc+5Ydo6KjzZog==} resolution: {integrity: sha512-Y66uDfUNbBzypsr0kELWrIz+5skicECrLUqlWuXawNSLUq3ltGlCwu6phboYYOTSnoTdHgTLrc+5Ydo6KjzZog==}
engines: {node: '>=16.0.0'} engines: {node: '>=16.0.0'}
@ -2418,6 +2710,11 @@ packages:
semver: 7.5.4 semver: 7.5.4
dev: true dev: true
/eslint-plugin-no-only-tests@3.1.0:
resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==}
engines: {node: '>=5.0.0'}
dev: true
/eslint-plugin-promise@6.1.1(eslint@8.48.0): /eslint-plugin-promise@6.1.1(eslint@8.48.0):
resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@ -2427,6 +2724,45 @@ packages:
eslint: 8.48.0 eslint: 8.48.0
dev: true dev: true
/eslint-plugin-unicorn@48.0.1(eslint@8.48.0):
resolution: {integrity: sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==}
engines: {node: '>=16'}
peerDependencies:
eslint: '>=8.44.0'
dependencies:
'@babel/helper-validator-identifier': 7.22.5
'@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0)
ci-info: 3.8.0
clean-regexp: 1.0.0
eslint: 8.48.0
esquery: 1.5.0
indent-string: 4.0.0
is-builtin-module: 3.2.1
jsesc: 3.0.2
lodash: 4.17.21
pluralize: 8.0.0
read-pkg-up: 7.0.1
regexp-tree: 0.1.27
regjsparser: 0.10.0
semver: 7.5.4
strip-indent: 3.0.0
dev: true
/eslint-plugin-unused-imports@3.0.0(@typescript-eslint/eslint-plugin@6.5.0)(eslint@8.48.0):
resolution: {integrity: sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
'@typescript-eslint/eslint-plugin': ^6.0.0
eslint: ^8.0.0
peerDependenciesMeta:
'@typescript-eslint/eslint-plugin':
optional: true
dependencies:
'@typescript-eslint/eslint-plugin': 6.5.0(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2)
eslint: 8.48.0
eslint-rule-composer: 0.3.0
dev: true
/eslint-plugin-vue@9.17.0(eslint@8.48.0): /eslint-plugin-vue@9.17.0(eslint@8.48.0):
resolution: {integrity: sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==} resolution: {integrity: sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==}
engines: {node: ^14.17.0 || >=16.0.0} engines: {node: ^14.17.0 || >=16.0.0}
@ -2445,6 +2781,34 @@ packages:
- supports-color - supports-color
dev: true dev: true
/eslint-plugin-yml@1.8.0(eslint@8.48.0):
resolution: {integrity: sha512-fgBiJvXD0P2IN7SARDJ2J7mx8t0bLdG6Zcig4ufOqW5hOvSiFxeUyc2g5I1uIm8AExbo26NNYCcTGZT0MXTsyg==}
engines: {node: ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: '>=6.0.0'
dependencies:
debug: 4.3.4
eslint: 8.48.0
lodash: 4.17.21
natural-compare: 1.4.0
yaml-eslint-parser: 1.2.2
transitivePeerDependencies:
- supports-color
dev: true
/eslint-rule-composer@0.3.0:
resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==}
engines: {node: '>=4.0.0'}
dev: true
/eslint-scope@5.1.1:
resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
engines: {node: '>=8.0.0'}
dependencies:
esrecurse: 4.3.0
estraverse: 4.3.0
dev: true
/eslint-scope@7.2.2: /eslint-scope@7.2.2:
resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@ -2527,6 +2891,11 @@ packages:
estraverse: 5.3.0 estraverse: 5.3.0
dev: true dev: true
/estraverse@4.3.0:
resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
engines: {node: '>=4.0'}
dev: true
/estraverse@5.3.0: /estraverse@5.3.0:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'} engines: {node: '>=4.0'}
@ -2681,6 +3050,14 @@ packages:
- supports-color - supports-color
dev: true dev: true
/find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
dependencies:
locate-path: 5.0.0
path-exists: 4.0.0
dev: true
/find-up@5.0.0: /find-up@5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -2806,6 +3183,12 @@ packages:
get-intrinsic: 1.2.1 get-intrinsic: 1.2.1
dev: true dev: true
/get-tsconfig@4.7.0:
resolution: {integrity: sha512-pmjiZ7xtB8URYm74PlGJozDNyhvsVLUcpBa8DZBG3bWHwaHa9bPiRpiSfovw+fjhwONSCWKRyk+JQHEGZmMrzw==}
dependencies:
resolve-pkg-maps: 1.0.0
dev: true
/glob-parent@5.1.2: /glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@ -2953,6 +3336,10 @@ packages:
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true dev: true
/hosted-git-info@2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
dev: true
/hosted-git-info@4.1.0: /hosted-git-info@4.1.0:
resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -3020,6 +3407,11 @@ packages:
engines: {node: '>=0.8.19'} engines: {node: '>=0.8.19'}
dev: true dev: true
/indent-string@4.0.0:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
engines: {node: '>=8'}
dev: true
/indent-string@5.0.0: /indent-string@5.0.0:
resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -3059,6 +3451,17 @@ packages:
engines: {node: '>= 0.10'} engines: {node: '>= 0.10'}
dev: true dev: true
/is-alphabetical@1.0.4:
resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
dev: true
/is-alphanumerical@1.0.4:
resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==}
dependencies:
is-alphabetical: 1.0.4
is-decimal: 1.0.4
dev: true
/is-array-buffer@3.0.2: /is-array-buffer@3.0.2:
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
dependencies: dependencies:
@ -3092,6 +3495,13 @@ packages:
has-tostringtag: 1.0.0 has-tostringtag: 1.0.0
dev: true dev: true
/is-builtin-module@3.2.1:
resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==}
engines: {node: '>=6'}
dependencies:
builtin-modules: 3.3.0
dev: true
/is-callable@1.2.7: /is-callable@1.2.7:
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -3110,6 +3520,10 @@ packages:
has-tostringtag: 1.0.0 has-tostringtag: 1.0.0
dev: true dev: true
/is-decimal@1.0.4:
resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==}
dev: true
/is-extglob@2.1.1: /is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -3132,6 +3546,10 @@ packages:
is-extglob: 2.1.1 is-extglob: 2.1.1
dev: true dev: true
/is-hexadecimal@1.0.4:
resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==}
dev: true
/is-negative-zero@2.0.2: /is-negative-zero@2.0.2:
resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -3241,6 +3659,17 @@ packages:
argparse: 2.0.1 argparse: 2.0.1
dev: true dev: true
/jsesc@0.5.0:
resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==}
hasBin: true
dev: true
/jsesc@3.0.2:
resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==}
engines: {node: '>=6'}
hasBin: true
dev: true
/json-buffer@3.0.1: /json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
dev: true dev: true
@ -3268,6 +3697,16 @@ packages:
minimist: 1.2.8 minimist: 1.2.8
dev: true dev: true
/jsonc-eslint-parser@2.3.0:
resolution: {integrity: sha512-9xZPKVYp9DxnM3sd1yAsh/d59iIaswDkai8oTxbursfKYbg/ibjX0IzFt35+VZ8iEW453TVTXztnRvYUQlAfUQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
acorn: 8.10.0
eslint-visitor-keys: 3.4.3
espree: 9.6.1
semver: 7.5.4
dev: true
/jsonc-parser@3.2.0: /jsonc-parser@3.2.0:
resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==}
dev: true dev: true
@ -3359,6 +3798,18 @@ packages:
wrap-ansi: 8.1.0 wrap-ansi: 8.1.0
dev: true dev: true
/local-pkg@0.4.3:
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
engines: {node: '>=14'}
dev: true
/locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
dependencies:
p-locate: 4.1.0
dev: true
/locate-path@6.0.0: /locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -3523,6 +3974,22 @@ packages:
resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
dev: true dev: true
/mdast-util-from-markdown@0.8.5:
resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==}
dependencies:
'@types/mdast': 3.0.12
mdast-util-to-string: 2.0.0
micromark: 2.11.4
parse-entities: 2.0.0
unist-util-stringify-position: 2.0.3
transitivePeerDependencies:
- supports-color
dev: true
/mdast-util-to-string@2.0.0:
resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==}
dev: true
/mdn-data@2.0.30: /mdn-data@2.0.30:
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
dev: true dev: true
@ -3575,6 +4042,15 @@ packages:
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
dev: true dev: true
/micromark@2.11.4:
resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==}
dependencies:
debug: 4.3.4
parse-entities: 2.0.0
transitivePeerDependencies:
- supports-color
dev: true
/micromatch@4.0.5: /micromatch@4.0.5:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'} engines: {node: '>=8.6'}
@ -3679,6 +4155,15 @@ packages:
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
dev: true dev: true
/normalize-package-data@2.5.0:
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
dependencies:
hosted-git-info: 2.8.9
resolve: 1.22.4
semver: 5.7.2
validate-npm-package-license: 3.0.4
dev: true
/normalize-package-data@3.0.3: /normalize-package-data@3.0.3:
resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -3795,6 +4280,13 @@ packages:
type-check: 0.4.0 type-check: 0.4.0
dev: true dev: true
/p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
dependencies:
p-try: 2.2.0
dev: true
/p-limit@3.1.0: /p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -3802,6 +4294,13 @@ packages:
yocto-queue: 0.1.0 yocto-queue: 0.1.0
dev: true dev: true
/p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
dependencies:
p-limit: 2.3.0
dev: true
/p-locate@5.0.0: /p-locate@5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -3809,6 +4308,11 @@ packages:
p-limit: 3.1.0 p-limit: 3.1.0
dev: true dev: true
/p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
dev: true
/pako@0.2.9: /pako@0.2.9:
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
dev: true dev: true
@ -3827,6 +4331,17 @@ packages:
hex-rgb: 4.3.0 hex-rgb: 4.3.0
dev: true dev: true
/parse-entities@2.0.0:
resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==}
dependencies:
character-entities: 1.2.4
character-entities-legacy: 1.1.4
character-reference-invalid: 1.1.4
is-alphanumerical: 1.0.4
is-decimal: 1.0.4
is-hexadecimal: 1.0.4
dev: true
/parse-json@5.2.0: /parse-json@5.2.0:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -3897,6 +4412,11 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/pluralize@8.0.0:
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
engines: {node: '>=4'}
dev: true
/postcss-html@1.5.0: /postcss-html@1.5.0:
resolution: {integrity: sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA==} resolution: {integrity: sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA==}
engines: {node: ^12 || >=14} engines: {node: ^12 || >=14}
@ -3966,12 +4486,6 @@ packages:
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
dev: true dev: true
/prettier@3.0.3:
resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==}
engines: {node: '>=14'}
hasBin: true
dev: true
/proxy-addr@2.0.7: /proxy-addr@2.0.7:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'} engines: {node: '>= 0.10'}
@ -4019,6 +4533,15 @@ packages:
unpipe: 1.0.0 unpipe: 1.0.0
dev: true dev: true
/read-pkg-up@7.0.1:
resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
engines: {node: '>=8'}
dependencies:
find-up: 4.1.0
read-pkg: 5.2.0
type-fest: 0.8.1
dev: true
/read-pkg-up@8.0.0: /read-pkg-up@8.0.0:
resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==} resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -4028,6 +4551,16 @@ packages:
type-fest: 1.4.0 type-fest: 1.4.0
dev: true dev: true
/read-pkg@5.2.0:
resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
engines: {node: '>=8'}
dependencies:
'@types/normalize-package-data': 2.4.1
normalize-package-data: 2.5.0
parse-json: 5.2.0
type-fest: 0.6.0
dev: true
/read-pkg@6.0.0: /read-pkg@6.0.0:
resolution: {integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==} resolution: {integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -4053,6 +4586,11 @@ packages:
strip-indent: 4.0.0 strip-indent: 4.0.0
dev: true dev: true
/regexp-tree@0.1.27:
resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==}
hasBin: true
dev: true
/regexp.prototype.flags@1.5.0: /regexp.prototype.flags@1.5.0:
resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -4062,6 +4600,13 @@ packages:
functions-have-names: 1.2.3 functions-have-names: 1.2.3
dev: true dev: true
/regjsparser@0.10.0:
resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==}
hasBin: true
dependencies:
jsesc: 0.5.0
dev: true
/remove-accents@0.4.2: /remove-accents@0.4.2:
resolution: {integrity: sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==} resolution: {integrity: sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==}
dev: false dev: false
@ -4081,6 +4626,10 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
dev: true
/resolve@1.22.4: /resolve@1.22.4:
resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==}
hasBin: true hasBin: true
@ -4203,6 +4752,11 @@ packages:
engines: {node: '>=8.16.0'} engines: {node: '>=8.16.0'}
dev: true dev: true
/semver@5.7.2:
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
hasBin: true
dev: true
/semver@6.3.1: /semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true hasBin: true
@ -4448,6 +5002,13 @@ packages:
engines: {node: '>=12'} engines: {node: '>=12'}
dev: true dev: true
/strip-indent@3.0.0:
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
engines: {node: '>=8'}
dependencies:
min-indent: 1.0.1
dev: true
/strip-indent@4.0.0: /strip-indent@4.0.0:
resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -4669,6 +5230,20 @@ packages:
strip-bom: 3.0.0 strip-bom: 3.0.0
dev: true dev: true
/tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: true
/tsutils@3.21.0(typescript@5.2.2):
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
engines: {node: '>= 6'}
peerDependencies:
typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
dependencies:
tslib: 1.14.1
typescript: 5.2.2
dev: true
/type-check@0.4.0: /type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -4681,6 +5256,16 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true dev: true
/type-fest@0.6.0:
resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
engines: {node: '>=8'}
dev: true
/type-fest@0.8.1:
resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
engines: {node: '>=8'}
dev: true
/type-fest@1.4.0: /type-fest@1.4.0:
resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -4761,6 +5346,12 @@ packages:
tiny-inflate: 1.0.3 tiny-inflate: 1.0.3
dev: true dev: true
/unist-util-stringify-position@2.0.3:
resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==}
dependencies:
'@types/unist': 2.0.8
dev: true
/universal-user-agent@6.0.0: /universal-user-agent@6.0.0:
resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==}
dev: false dev: false
@ -5093,6 +5684,15 @@ packages:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true dev: true
/yaml-eslint-parser@1.2.2:
resolution: {integrity: sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==}
engines: {node: ^14.17.0 || >=16.0.0}
dependencies:
eslint-visitor-keys: 3.4.3
lodash: 4.17.21
yaml: 2.3.1
dev: true
/yaml@2.3.1: /yaml@2.3.1:
resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==}
engines: {node: '>= 14'} engines: {node: '>= 14'}

View File

@ -1,36 +1,43 @@
import { URL, fileURLToPath } from "node:url"; import process from "node:process"
import { defineConfig, loadEnv } from "vitepress"; import { URL, fileURLToPath } from "node:url"
import ElementPlus from "unplugin-element-plus/vite"; import { defineConfig, loadEnv } from "vitepress"
import ElementPlus from "unplugin-element-plus/vite"
import markdownConfig from "./config/markdownConfig"; // For use with loading Markdown plugins import markdownConfig from "./config/markdownConfig"
import themeConfig from "./config/themeConfig"; // Theme related config
import headConfig from "./config/headConfig"; // Provides how to generate Meta head tags
import generateMeta from "./config/hooks/generateMeta"; // Enhanced meta generation // For use with loading Markdown plugins
import generateFeed from "./config/hooks/generateFeed"; // Allows generation of RSS feed import themeConfig from "./config/themeConfig"
import generateOgImages from "./config/hooks/generateOgImages";
const title = "Tachiyomi"; // Theme related config
const description = "Read your favorite manga, webtoons, comics, and more easier than ever on your Android."; import headConfig from "./config/headConfig" // Provides how to generate Meta head tags
const env = loadEnv("", process.cwd()); import generateMeta from "./config/hooks/generateMeta"
const hostname: string = env.VITE_HOSTNAME || "http://localhost:4173";
// Enhanced meta generation
import generateFeed from "./config/hooks/generateFeed" // Allows generation of RSS feed
import generateOgImages from "./config/hooks/generateOgImages"
const title = "Tachiyomi"
const description = "Read your favorite manga, webtoons, comics, and more easier than ever on your Android."
const env = loadEnv("", process.cwd())
const hostname: string = env.VITE_HOSTNAME || "http://localhost:4173"
export default defineConfig({ export default defineConfig({
lastUpdated: true, lastUpdated: true,
cleanUrls: true, cleanUrls: true,
title: title, title,
description: description, description,
sitemap: { sitemap: {
hostname: hostname, hostname,
}, },
head: headConfig, head: headConfig,
markdown: markdownConfig, markdown: markdownConfig,
themeConfig: themeConfig, themeConfig,
transformHead: async (context) => generateMeta(context, hostname), transformHead: async (context) => generateMeta(context, hostname),
buildEnd: async (context) => { buildEnd: async (context) => {
generateFeed(context, hostname); generateFeed(context, hostname)
generateOgImages(context); generateOgImages(context)
}, },
vite: { vite: {
resolve: { resolve: {
@ -39,20 +46,20 @@ export default defineConfig({
// Used to show the release version on navbar. // Used to show the release version on navbar.
find: /^.*\/VPNavBarMenu\.vue$/, find: /^.*\/VPNavBarMenu\.vue$/,
replacement: fileURLToPath( replacement: fileURLToPath(
new URL("./theme/components/CustomNavBarMenu.vue", import.meta.url) new URL("./theme/components/CustomNavBarMenu.vue", import.meta.url),
), ),
}, },
{ {
find: /^.*VPNavScreenMenu\.vue$/, find: /^.*VPNavScreenMenu\.vue$/,
replacement: fileURLToPath( replacement: fileURLToPath(
new URL("./theme/components/CustomNavScreenMenu.vue", import.meta.url) new URL("./theme/components/CustomNavScreenMenu.vue", import.meta.url),
), ),
}, },
] ],
}, },
plugins: [ElementPlus({})], plugins: [ElementPlus({})],
ssr: { ssr: {
noExternal: ["element-plus"], noExternal: ["element-plus"],
}, },
}, },
}); })

View File

@ -1,6 +1,6 @@
export const GITHUB_EXTENSION_JSON = export const GITHUB_EXTENSION_JSON
"https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/index.json"; = "https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/index.json"
export const GITHUB_STABLE_API = "https://api.github.com/repos/tachiyomiorg/tachiyomi/releases/latest"; export const GITHUB_STABLE_API = "https://api.github.com/repos/tachiyomiorg/tachiyomi/releases/latest"
export const GITHUB_STABLE_RELEASE = "https://github.com/tachiyomiorg/tachiyomi/releases/latest"; export const GITHUB_STABLE_RELEASE = "https://github.com/tachiyomiorg/tachiyomi/releases/latest"
export const GITHUB_PREVIEW_API = "https://api.github.com/repos/tachiyomiorg/android-app-preview/releases/latest"; export const GITHUB_PREVIEW_API = "https://api.github.com/repos/tachiyomiorg/android-app-preview/releases/latest"
export const GITHUB_PREVIEW_RELEASE = "https://github.com/tachiyomiorg/android-app-preview/releases/latest"; export const GITHUB_PREVIEW_RELEASE = "https://github.com/tachiyomiorg/android-app-preview/releases/latest"

View File

@ -1,4 +1,4 @@
import type { HeadConfig } from "vitepress"; import type { HeadConfig } from "vitepress"
const headConfig: HeadConfig[] = [ const headConfig: HeadConfig[] = [
["meta", { name: "darkreader-lock" }], ["meta", { name: "darkreader-lock" }],
@ -54,6 +54,6 @@ const headConfig: HeadConfig[] = [
], ],
["meta", { property: "og:locale", content: "en_US" }], ["meta", { property: "og:locale", content: "en_US" }],
["meta", { property: "og:type", content: "website" }], ["meta", { property: "og:type", content: "website" }],
]; ]
export default headConfig; export default headConfig

View File

@ -1,7 +1,7 @@
import path from "path"; import path from "node:path"
import { writeFileSync } from "fs"; import { writeFileSync } from "node:fs"
import { Feed } from "feed"; import { Feed } from "feed"
import { createContentLoader, type SiteConfig } from "vitepress"; import { type SiteConfig, createContentLoader } from "vitepress"
async function generateFeed(config: SiteConfig, hostname: string) { async function generateFeed(config: SiteConfig, hostname: string) {
const feed = new Feed({ const feed = new Feed({
@ -13,23 +13,23 @@ async function generateFeed(config: SiteConfig, hostname: string) {
image: `${hostname}/img/logo.png`, image: `${hostname}/img/logo.png`,
favicon: `${hostname}/favicon.ico`, favicon: `${hostname}/favicon.ico`,
copyright: `Copyright © 2015 - ${new Date().getFullYear()} Javier Tomás`, copyright: `Copyright © 2015 - ${new Date().getFullYear()} Javier Tomás`,
}); })
const posts = await createContentLoader("news/*.md", { const posts = await createContentLoader("news/*.md", {
excerpt: true, excerpt: true,
render: true, render: true,
}).load(); }).load()
// Filter everything that"s not of type `article` (e.g. index.md) // Filter everything that"s not of type `article` (e.g. index.md)
const filteredPosts = posts.filter((post) => post.frontmatter.type === "article"); const filteredPosts = posts.filter((post) => post.frontmatter.type === "article")
filteredPosts.sort((a, b) => +new Date(b.frontmatter.date as string) - +new Date(a.frontmatter.date as string)); filteredPosts.sort((a, b) => +new Date(b.frontmatter.date as string) - +new Date(a.frontmatter.date as string))
for (const { url, excerpt, frontmatter, html } of filteredPosts) { for (const { url, frontmatter, html } of filteredPosts) {
const fullUrl = `${hostname}${url}`; const fullUrl = `${hostname}${url}`
// Strip `​` from `html` string // Strip `​` from `html` string
const content = html?.replace(/​/g, ""); const content = html?.replace(/​/g, "")
feed.addItem({ feed.addItem({
title: frontmatter.title, title: frontmatter.title,
@ -37,12 +37,12 @@ async function generateFeed(config: SiteConfig, hostname: string) {
link: fullUrl, link: fullUrl,
// description: excerpt, // description: excerpt,
description: frontmatter.description, description: frontmatter.description,
content: content, content,
date: frontmatter.date, date: frontmatter.date,
}); })
} }
writeFileSync(path.join(config.outDir, "feed.rss"), feed.rss2()); writeFileSync(path.join(config.outDir, "feed.rss"), feed.rss2())
} }
export default generateFeed; export default generateFeed

View File

@ -1,21 +1,21 @@
import type { HeadConfig, TransformContext } from "vitepress"; import type { HeadConfig, TransformContext } from "vitepress"
const generateMeta = (context: TransformContext, hostname: string) => { function generateMeta(context: TransformContext, hostname: string) {
const head: HeadConfig[] = []; const head: HeadConfig[] = []
const { pageData } = context; const { pageData } = context
const url = `${hostname}/${pageData.relativePath.replace(/((^|\/)index)?\.md$/, "$2")}`; const url = `${hostname}/${pageData.relativePath.replace(/((^|\/)index)?\.md$/, "$2")}`
head.push(["link", { rel: "canonical", href: url }]); head.push(["link", { rel: "canonical", href: url }])
head.push(["meta", { property: "og:url", content: url }]); head.push(["meta", { property: "og:url", content: url }])
head.push(["meta", { name: "twitter:url", content: url }]); head.push(["meta", { name: "twitter:url", content: url }])
head.push(["meta", { name: "twitter:card", content: "summary_large_image" }]); head.push(["meta", { name: "twitter:card", content: "summary_large_image" }])
if (pageData.frontmatter.theme) { if (pageData.frontmatter.theme) {
head.push(["meta", { name: "theme-color", content: pageData.frontmatter.theme }]); head.push(["meta", { name: "theme-color", content: pageData.frontmatter.theme }])
} }
if (pageData.frontmatter.type) { if (pageData.frontmatter.type) {
head.push(["meta", { property: "og:type", content: pageData.frontmatter.type }]); head.push(["meta", { property: "og:type", content: pageData.frontmatter.type }])
} }
if (pageData.frontmatter.customMetaTitle) { if (pageData.frontmatter.customMetaTitle) {
head.push([ head.push([
@ -24,18 +24,18 @@ const generateMeta = (context: TransformContext, hostname: string) => {
property: "og:title", property: "og:title",
content: pageData.frontmatter.customMetaTitle, content: pageData.frontmatter.customMetaTitle,
}, },
]); ])
head.push([ head.push([
"meta", "meta",
{ {
name: "twitter:title", name: "twitter:title",
content: pageData.frontmatter.customMetaTitle, content: pageData.frontmatter.customMetaTitle,
}, },
]); ])
head.push(["meta", { property: "og:site_name", content: "" }]); head.push(["meta", { property: "og:site_name", content: "" }])
} else { } else {
head.push(["meta", { property: "og:title", content: pageData.frontmatter.title }]); head.push(["meta", { property: "og:title", content: pageData.frontmatter.title }])
head.push(["meta", { name: "twitter:title", content: pageData.frontmatter.title }]); head.push(["meta", { name: "twitter:title", content: pageData.frontmatter.title }])
} }
if (pageData.frontmatter.description) { if (pageData.frontmatter.description) {
head.push([ head.push([
@ -44,14 +44,14 @@ const generateMeta = (context: TransformContext, hostname: string) => {
property: "og:description", property: "og:description",
content: pageData.frontmatter.description, content: pageData.frontmatter.description,
}, },
]); ])
head.push([ head.push([
"meta", "meta",
{ {
name: "twitter:description", name: "twitter:description",
content: pageData.frontmatter.description, content: pageData.frontmatter.description,
}, },
]); ])
} }
if (pageData.frontmatter.image) { if (pageData.frontmatter.image) {
head.push([ head.push([
@ -60,30 +60,30 @@ const generateMeta = (context: TransformContext, hostname: string) => {
property: "og:image", property: "og:image",
content: `${hostname}/${pageData.frontmatter.image.replace(/^\//, "")}`, content: `${hostname}/${pageData.frontmatter.image.replace(/^\//, "")}`,
}, },
]); ])
head.push([ head.push([
"meta", "meta",
{ {
name: "twitter:image", name: "twitter:image",
content: `${hostname}/${pageData.frontmatter.image.replace(/^\//, "")}`, content: `${hostname}/${pageData.frontmatter.image.replace(/^\//, "")}`,
}, },
]); ])
} else { } else {
const url = pageData.filePath.replace("index.md", "").replace(".md", ""); const url = pageData.filePath.replace("index.md", "").replace(".md", "")
const imageUrl = `${url}/__og_image__/og.png`.replace(/\/\//g, "/").replace(/^\//, ""); const imageUrl = `${url}/__og_image__/og.png`.replace(/\/\//g, "/").replace(/^\//, "")
head.push(["meta", { property: "og:image", content: `${hostname}/${imageUrl}` }]); head.push(["meta", { property: "og:image", content: `${hostname}/${imageUrl}` }])
head.push(["meta", { property: "og:image:width", content: "1200" }]); head.push(["meta", { property: "og:image:width", content: "1200" }])
head.push(["meta", { property: "og:image:height", content: "628" }]); head.push(["meta", { property: "og:image:height", content: "628" }])
head.push(["meta", { property: "og:image:type", content: "image/png" }]); head.push(["meta", { property: "og:image:type", content: "image/png" }])
head.push(["meta", { property: "og:image:alt", content: pageData.frontmatter.title }]); head.push(["meta", { property: "og:image:alt", content: pageData.frontmatter.title }])
head.push(["meta", { name: "twitter:image", content: `${hostname}/${imageUrl}` }]); head.push(["meta", { name: "twitter:image", content: `${hostname}/${imageUrl}` }])
head.push(["meta", { name: "twitter:image:width", content: "1200" }]); head.push(["meta", { name: "twitter:image:width", content: "1200" }])
head.push(["meta", { name: "twitter:image:height", content: "628" }]); head.push(["meta", { name: "twitter:image:height", content: "628" }])
head.push(["meta", { name: "twitter:image:alt", content: pageData.frontmatter.title }]); head.push(["meta", { name: "twitter:image:alt", content: pageData.frontmatter.title }])
} }
if (pageData.frontmatter.tag) { if (pageData.frontmatter.tag) {
head.push(["meta", { property: "article:tag", content: pageData.frontmatter.tag }]); head.push(["meta", { property: "article:tag", content: pageData.frontmatter.tag }])
} }
if (pageData.frontmatter.date) { if (pageData.frontmatter.date) {
head.push([ head.push([
@ -92,7 +92,7 @@ const generateMeta = (context: TransformContext, hostname: string) => {
property: "article:published_time", property: "article:published_time",
content: pageData.frontmatter.date, content: pageData.frontmatter.date,
}, },
]); ])
} }
if (pageData.lastUpdated && pageData.frontmatter.lastUpdated !== false) { if (pageData.lastUpdated && pageData.frontmatter.lastUpdated !== false) {
head.push([ head.push([
@ -101,10 +101,10 @@ const generateMeta = (context: TransformContext, hostname: string) => {
property: "article:modified_time", property: "article:modified_time",
content: new Date(pageData.lastUpdated).toISOString(), content: new Date(pageData.lastUpdated).toISOString(),
}, },
]); ])
} }
return head; return head
}; }
export default generateMeta; export default generateMeta

View File

@ -1,17 +1,17 @@
import { mkdir, readFile, writeFile } from "fs/promises"; import { mkdir, readFile, writeFile } from "node:fs/promises"
import { dirname, resolve } from "path"; import { dirname, resolve } from "node:path"
import { fileURLToPath } from "url"; import { fileURLToPath } from "node:url"
import { createContentLoader } from "vitepress"; import { createContentLoader } from "vitepress"
import type { ContentData, SiteConfig } from "vitepress"; import type { ContentData, SiteConfig } from "vitepress"
import { type SatoriOptions, satoriVue } from "x-satori/vue"; import { type SatoriOptions, satoriVue } from "x-satori/vue"
import { renderAsync } from "@resvg/resvg-js"; import { renderAsync } from "@resvg/resvg-js"
const __dirname = dirname(fileURLToPath(import.meta.url)); const __dirname = dirname(fileURLToPath(import.meta.url))
const __fonts = resolve(__dirname, "../../fonts"); const __fonts = resolve(__dirname, "../../fonts")
async function generateOgImages(config: SiteConfig) { async function generateOgImages(config: SiteConfig) {
const pages = await createContentLoader("**/*.md", { excerpt: true }).load(); const pages = await createContentLoader("**/*.md", { excerpt: true }).load()
const template = await readFile(resolve(__dirname, "../../theme/components/OgImageTemplate.vue"), "utf-8"); const template = await readFile(resolve(__dirname, "../../theme/components/OgImageTemplate.vue"), "utf-8")
const fonts: SatoriOptions["fonts"] = [ const fonts: SatoriOptions["fonts"] = [
{ {
@ -38,9 +38,9 @@ async function generateOgImages(config: SiteConfig) {
weight: 700, weight: 700,
style: "normal", style: "normal",
}, },
]; ]
const filteredPages = pages.filter((p) => p.frontmatter.image === undefined); const filteredPages = pages.filter((p) => p.frontmatter.image === undefined)
for (const page of filteredPages) { for (const page of filteredPages) {
await generateImage({ await generateImage({
@ -48,21 +48,21 @@ async function generateOgImages(config: SiteConfig) {
template, template,
outDir: config.outDir, outDir: config.outDir,
fonts, fonts,
}); })
} }
} }
export default generateOgImages; export default generateOgImages
interface GenerateImagesOptions { interface GenerateImagesOptions {
page: ContentData; page: ContentData
template: string; template: string
outDir: string; outDir: string
fonts: SatoriOptions["fonts"]; fonts: SatoriOptions["fonts"]
} }
async function generateImage({ page, template, outDir, fonts }: GenerateImagesOptions) { async function generateImage({ page, template, outDir, fonts }: GenerateImagesOptions) {
const { frontmatter, url } = page; const { frontmatter, url } = page
const options: SatoriOptions = { const options: SatoriOptions = {
width: 1200, width: 1200,
@ -79,21 +79,21 @@ async function generateImage({ page, template, outDir, fonts }: GenerateImagesOp
: frontmatter.description, : frontmatter.description,
dir: url.startsWith("/docs/faq/") ? "FAQ" : url.startsWith("/docs/guides/") ? "Guide" : undefined, dir: url.startsWith("/docs/faq/") ? "FAQ" : url.startsWith("/docs/guides/") ? "Guide" : undefined,
}, },
}; }
const svg = await satoriVue(options, template); const svg = await satoriVue(options, template)
const render = await renderAsync(svg, { const render = await renderAsync(svg, {
fitTo: { fitTo: {
mode: "width", mode: "width",
value: 1200, value: 1200,
}, },
}); })
const outputFolder = resolve(outDir, url.substring(1), "__og_image__"); const outputFolder = resolve(outDir, url.substring(1), "__og_image__")
const outputFile = resolve(outputFolder, "og.png"); const outputFile = resolve(outputFolder, "og.png")
await mkdir(outputFolder, { recursive: true }); await mkdir(outputFolder, { recursive: true })
return await writeFile(outputFile, render.asPng()); return await writeFile(outputFile, render.asPng())
} }

View File

@ -1,14 +1,14 @@
import type { MarkdownOptions } from "vitepress"; import type { MarkdownOptions } from "vitepress"
import { attrs } from "@mdit/plugin-attrs"; import { attrs } from "@mdit/plugin-attrs"
import { figure } from "@mdit/plugin-figure"; import { figure } from "@mdit/plugin-figure"
import { imgLazyload } from "@mdit/plugin-img-lazyload"; import { imgLazyload } from "@mdit/plugin-img-lazyload"
import { imgMark } from "@mdit/plugin-img-mark"; import { imgMark } from "@mdit/plugin-img-mark"
import { imgSize } from "@mdit/plugin-img-size"; import { imgSize } from "@mdit/plugin-img-size"
import { include } from "@mdit/plugin-include"; import { include } from "@mdit/plugin-include"
import { tabsMarkdownPlugin } from "vitepress-plugin-tabs"; import { tabsMarkdownPlugin } from "vitepress-plugin-tabs"
import shortcode_plugin from "markdown-it-shortcode-tag"; import shortcode_plugin from "markdown-it-shortcode-tag"
import shortcodes from "./shortcodes"; import shortcodes from "./shortcodes"
const markdownConfig: MarkdownOptions = { const markdownConfig: MarkdownOptions = {
config: (md) => { config: (md) => {
@ -22,8 +22,8 @@ const markdownConfig: MarkdownOptions = {
currentPath: (env) => env.filePath, currentPath: (env) => env.filePath,
}) })
.use(tabsMarkdownPlugin) .use(tabsMarkdownPlugin)
.use(shortcode_plugin, shortcodes); .use(shortcode_plugin, shortcodes)
}, },
}; }
export default markdownConfig; export default markdownConfig

View File

@ -1,4 +1,4 @@
import type { DefaultTheme } from "vitepress"; import type { DefaultTheme } from "vitepress"
const nav: DefaultTheme.NavItem[] = [ const nav: DefaultTheme.NavItem[] = [
{ {
@ -24,6 +24,6 @@ const nav: DefaultTheme.NavItem[] = [
}, },
], ],
}, },
]; ]
export default nav; export default nav

View File

@ -1,4 +1,4 @@
import type { DefaultTheme } from "vitepress"; import type { DefaultTheme } from "vitepress"
const sidebar: DefaultTheme.SidebarMulti = { const sidebar: DefaultTheme.SidebarMulti = {
"/download/": defaultSidebar(), "/download/": defaultSidebar(),
@ -8,7 +8,7 @@ const sidebar: DefaultTheme.SidebarMulti = {
"/changelogs/": defaultSidebar(), "/changelogs/": defaultSidebar(),
"/news/": defaultSidebar(), "/news/": defaultSidebar(),
"/sandbox/": defaultSidebar(), "/sandbox/": defaultSidebar(),
}; }
function defaultSidebar(): DefaultTheme.SidebarItem[] { function defaultSidebar(): DefaultTheme.SidebarItem[] {
return [ return [
@ -137,7 +137,7 @@ function defaultSidebar(): DefaultTheme.SidebarItem[] {
}, },
], ],
}, },
]; ]
} }
export default sidebar; export default sidebar

View File

@ -1,21 +1,21 @@
export function simpleLangName(code: string) { export function simpleLangName(code: string) {
if (code === "all") { if (code === "all") {
return "All"; return "All"
} }
const namesInEnglish = new Intl.DisplayNames(["en"], { type: "language" }); const namesInEnglish = new Intl.DisplayNames(["en"], { type: "language" })
return capitalize(namesInEnglish.of(code)!, "en"); return capitalize(namesInEnglish.of(code)!, "en")
} }
export function langName(code: string) { export function langName(code: string) {
if (code === "all") { if (code === "all") {
return "All"; return "All"
} }
const namesInEnglish = new Intl.DisplayNames(["en"], { type: "language" }); const namesInEnglish = new Intl.DisplayNames(["en"], { type: "language" })
const namesInNative = new Intl.DisplayNames([code], { type: "language" }); const namesInNative = new Intl.DisplayNames([code], { type: "language" })
return `${capitalize(namesInEnglish.of(code)!, "en")} - ${capitalize(namesInNative.of(code)!, code)}`; return `${capitalize(namesInEnglish.of(code)!, "en")} - ${capitalize(namesInNative.of(code)!, code)}`
} }
function capitalize(string: string, locale: string) { function capitalize(string: string, locale: string) {
return string.charAt(0).toLocaleUpperCase(locale) + string.substring(1); return string.charAt(0).toLocaleUpperCase(locale) + string.substring(1)
} }

View File

@ -1,86 +1,91 @@
const iconMappings = { const iconMappings = {
alertDecagramOutline: `<svg originalIcon="alertDecagramOutline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M23,12L20.56,14.78L20.9,18.46L17.29,19.28L15.4,22.46L12,21L8.6,22.47L6.71,19.29L3.1,18.47L3.44,14.78L1,12L3.44,9.21L3.1,5.53L6.71,4.72L8.6,1.54L12,3L15.4,1.54L17.29,4.72L20.9,5.54L20.56,9.22L23,12M20.33,12L18.5,9.89L18.74,7.1L16,6.5L14.58,4.07L12,5.18L9.42,4.07L8,6.5L5.26,7.09L5.5,9.88L3.67,12L5.5,14.1L5.26,16.9L8,17.5L9.42,19.93L12,18.81L14.58,19.92L16,17.5L18.74,16.89L18.5,14.1L20.33,12M11,15H13V17H11V15M11,7H13V13H11V7" /></svg>`, alertDecagramOutline: '<svg originalIcon="alertDecagramOutline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M23,12L20.56,14.78L20.9,18.46L17.29,19.28L15.4,22.46L12,21L8.6,22.47L6.71,19.29L3.1,18.47L3.44,14.78L1,12L3.44,9.21L3.1,5.53L6.71,4.72L8.6,1.54L12,3L15.4,1.54L17.29,4.72L20.9,5.54L20.56,9.22L23,12M20.33,12L18.5,9.89L18.74,7.1L16,6.5L14.58,4.07L12,5.18L9.42,4.07L8,6.5L5.26,7.09L5.5,9.88L3.67,12L5.5,14.1L5.26,16.9L8,17.5L9.42,19.93L12,18.81L14.58,19.92L16,17.5L18.74,16.89L18.5,14.1L20.33,12M11,15H13V17H11V15M11,7H13V13H11V7" /></svg>',
backupRestore: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,3A9,9 0 0,0 3,12H0L4,16L8,12H5A7,7 0 0,1 12,5A7,7 0 0,1 19,12A7,7 0 0,1 12,19C10.5,19 9.09,18.5 7.94,17.7L6.5,19.14C8.04,20.3 9.94,21 12,21A9,9 0 0,0 21,12A9,9 0 0,0 12,3M14,12A2,2 0 0,0 12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12Z" /></svg>`, backupRestore: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,3A9,9 0 0,0 3,12H0L4,16L8,12H5A7,7 0 0,1 12,5A7,7 0 0,1 19,12A7,7 0 0,1 12,19C10.5,19 9.09,18.5 7.94,17.7L6.5,19.14C8.04,20.3 9.94,21 12,21A9,9 0 0,0 21,12A9,9 0 0,0 12,3M14,12A2,2 0 0,0 12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12Z" /></svg>',
bookmarkBoxOutline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 20H18V22H4C2.9 22 2 21.1 2 20V6H4V20M22 4V16C22 17.1 21.1 18 20 18H8C6.9 18 6 17.1 6 16V4C6 2.9 6.9 2 8 2H20C21.1 2 22 2.9 22 4M20 4H8V16H20V4M18 6H13V13L15.5 11.5L18 13V6Z" /></svg>`, bookmarkBoxOutline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 20H18V22H4C2.9 22 2 21.1 2 20V6H4V20M22 4V16C22 17.1 21.1 18 20 18H8C6.9 18 6 17.1 6 16V4C6 2.9 6.9 2 8 2H20C21.1 2 22 2.9 22 4M20 4H8V16H20V4M18 6H13V13L15.5 11.5L18 13V6Z" /></svg>',
bookOpenOutline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21,4H3A2,2 0 0,0 1,6V19A2,2 0 0,0 3,21H21A2,2 0 0,0 23,19V6A2,2 0 0,0 21,4M3,19V6H11V19H3M21,19H13V6H21V19M14,9.5H20V11H14V9.5M14,12H20V13.5H14V12M14,14.5H20V16H14V14.5Z" /></svg>`, bookOpenOutline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21,4H3A2,2 0 0,0 1,6V19A2,2 0 0,0 3,21H21A2,2 0 0,0 23,19V6A2,2 0 0,0 21,4M3,19V6H11V19H3M21,19H13V6H21V19M14,9.5H20V11H14V9.5M14,12H20V13.5H14V12M14,14.5H20V16H14V14.5Z" /></svg>',
cloudOffOutline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19.8 22.6L17.15 20H6.5Q4.2 20 2.6 18.4T1 14.5Q1 12.58 2.19 11.08 3.38 9.57 5.25 9.15 5.33 8.95 5.4 8.76 5.5 8.57 5.55 8.35L1.4 4.2L2.8 2.8L21.2 21.2M6.5 18H15.15L7.1 9.95Q7.05 10.23 7.03 10.5 7 10.73 7 11H6.5Q5.05 11 4.03 12.03 3 13.05 3 14.5 3 15.95 4.03 17 5.05 18 6.5 18M11.13 14M21.6 18.75L20.15 17.35Q20.58 17 20.79 16.54 21 16.08 21 15.5 21 14.45 20.27 13.73 19.55 13 18.5 13H17V11Q17 8.93 15.54 7.46 14.08 6 12 6 11.33 6 10.7 6.16 10.07 6.33 9.5 6.68L8.05 5.23Q8.93 4.63 9.91 4.31 10.9 4 12 4 14.93 4 16.96 6.04 19 8.07 19 11 20.73 11.2 21.86 12.5 23 13.78 23 15.5 23 16.5 22.63 17.31 22.25 18.15 21.6 18.75M14.83 12.03Z" /></svg>`, cloudOffOutline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19.8 22.6L17.15 20H6.5Q4.2 20 2.6 18.4T1 14.5Q1 12.58 2.19 11.08 3.38 9.57 5.25 9.15 5.33 8.95 5.4 8.76 5.5 8.57 5.55 8.35L1.4 4.2L2.8 2.8L21.2 21.2M6.5 18H15.15L7.1 9.95Q7.05 10.23 7.03 10.5 7 10.73 7 11H6.5Q5.05 11 4.03 12.03 3 13.05 3 14.5 3 15.95 4.03 17 5.05 18 6.5 18M11.13 14M21.6 18.75L20.15 17.35Q20.58 17 20.79 16.54 21 16.08 21 15.5 21 14.45 20.27 13.73 19.55 13 18.5 13H17V11Q17 8.93 15.54 7.46 14.08 6 12 6 11.33 6 10.7 6.16 10.07 6.33 9.5 6.68L8.05 5.23Q8.93 4.63 9.91 4.31 10.9 4 12 4 14.93 4 16.96 6.04 19 8.07 19 11 20.73 11.2 21.86 12.5 23 13.78 23 15.5 23 16.5 22.63 17.31 22.25 18.15 21.6 18.75M14.83 12.03Z" /></svg>',
codeTags: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.6,16.6L19.2,12L14.6,7.4L16,6L22,12L16,18L14.6,16.6M9.4,16.6L4.8,12L9.4,7.4L8,6L2,12L8,18L9.4,16.6Z" /></svg>`, codeTags: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.6,16.6L19.2,12L14.6,7.4L16,6L22,12L16,18L14.6,16.6M9.4,16.6L4.8,12L9.4,7.4L8,6L2,12L8,18L9.4,16.6Z" /></svg>',
cog: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z" /></svg>`, cog: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z" /></svg>',
compassOutline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7,17L10.2,10.2L17,7L13.8,13.8L7,17M12,11.1A0.9,0.9 0 0,0 11.1,12A0.9,0.9 0 0,0 12,12.9A0.9,0.9 0 0,0 12.9,12A0.9,0.9 0 0,0 12,11.1M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" /></svg>`, compassOutline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7,17L10.2,10.2L17,7L13.8,13.8L7,17M12,11.1A0.9,0.9 0 0,0 11.1,12A0.9,0.9 0 0,0 12,12.9A0.9,0.9 0 0,0 12.9,12A0.9,0.9 0 0,0 12,11.1M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" /></svg>',
dotsHorizontal: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z" /></svg>`, dotsHorizontal: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z" /></svg>',
downloadOutline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13,5V11H14.17L12,13.17L9.83,11H11V5H13M15,3H9V9H5L12,16L19,9H15V3M19,18H5V20H19V18Z" /></svg>`, downloadOutline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13,5V11H14.17L12,13.17L9.83,11H11V5H13M15,3H9V9H5L12,16L19,9H15V3M19,18H5V20H19V18Z" /></svg>',
glasses: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3,10C2.76,10 2.55,10.09 2.41,10.25C2.27,10.4 2.21,10.62 2.24,10.86L2.74,13.85C2.82,14.5 3.4,15 4,15H7C7.64,15 8.36,14.44 8.5,13.82L9.56,10.63C9.6,10.5 9.57,10.31 9.5,10.19C9.39,10.07 9.22,10 9,10H3M7,17H4C2.38,17 0.96,15.74 0.76,14.14L0.26,11.15C0.15,10.3 0.39,9.5 0.91,8.92C1.43,8.34 2.19,8 3,8H9C9.83,8 10.58,8.35 11.06,8.96C11.17,9.11 11.27,9.27 11.35,9.45C11.78,9.36 12.22,9.36 12.64,9.45C12.72,9.27 12.82,9.11 12.94,8.96C13.41,8.35 14.16,8 15,8H21C21.81,8 22.57,8.34 23.09,8.92C23.6,9.5 23.84,10.3 23.74,11.11L23.23,14.18C23.04,15.74 21.61,17 20,17H17C15.44,17 13.92,15.81 13.54,14.3L12.64,11.59C12.26,11.31 11.73,11.31 11.35,11.59L10.43,14.37C10.07,15.82 8.56,17 7,17M15,10C14.78,10 14.61,10.07 14.5,10.19C14.42,10.31 14.4,10.5 14.45,10.7L15.46,13.75C15.64,14.44 16.36,15 17,15H20C20.59,15 21.18,14.5 21.25,13.89L21.76,10.82C21.79,10.62 21.73,10.4 21.59,10.25C21.45,10.09 21.24,10 21,10H15Z" /></svg>`, glasses: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3,10C2.76,10 2.55,10.09 2.41,10.25C2.27,10.4 2.21,10.62 2.24,10.86L2.74,13.85C2.82,14.5 3.4,15 4,15H7C7.64,15 8.36,14.44 8.5,13.82L9.56,10.63C9.6,10.5 9.57,10.31 9.5,10.19C9.39,10.07 9.22,10 9,10H3M7,17H4C2.38,17 0.96,15.74 0.76,14.14L0.26,11.15C0.15,10.3 0.39,9.5 0.91,8.92C1.43,8.34 2.19,8 3,8H9C9.83,8 10.58,8.35 11.06,8.96C11.17,9.11 11.27,9.27 11.35,9.45C11.78,9.36 12.22,9.36 12.64,9.45C12.72,9.27 12.82,9.11 12.94,8.96C13.41,8.35 14.16,8 15,8H21C21.81,8 22.57,8.34 23.09,8.92C23.6,9.5 23.84,10.3 23.74,11.11L23.23,14.18C23.04,15.74 21.61,17 20,17H17C15.44,17 13.92,15.81 13.54,14.3L12.64,11.59C12.26,11.31 11.73,11.31 11.35,11.59L10.43,14.37C10.07,15.82 8.56,17 7,17M15,10C14.78,10 14.61,10.07 14.5,10.19C14.42,10.31 14.4,10.5 14.45,10.7L15.46,13.75C15.64,14.44 16.36,15 17,15H20C20.59,15 21.18,14.5 21.25,13.89L21.76,10.82C21.79,10.62 21.73,10.4 21.59,10.25C21.45,10.09 21.24,10 21,10H15Z" /></svg>',
helpCircleOutline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11,18H13V16H11V18M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,6A4,4 0 0,0 8,10H10A2,2 0 0,1 12,8A2,2 0 0,1 14,10C14,12 11,11.75 11,15H13C13,12.75 16,12.5 16,10A4,4 0 0,0 12,6Z" /></svg>`, helpCircleOutline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11,18H13V16H11V18M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,6A4,4 0 0,0 8,10H10A2,2 0 0,1 12,8A2,2 0 0,1 14,10C14,12 11,11.75 11,15H13C13,12.75 16,12.5 16,10A4,4 0 0,0 12,6Z" /></svg>',
history: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.5,8H12V13L16.28,15.54L17,14.33L13.5,12.25V8M13,3A9,9 0 0,0 4,12H1L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,20 10.5,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3" /></svg>`, history: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.5,8H12V13L16.28,15.54L17,14.33L13.5,12.25V8M13,3A9,9 0 0,0 4,12H1L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,20 10.5,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3" /></svg>',
informationOutline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z" /></svg>`, informationOutline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z" /></svg>',
labelOutline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16,17H5V7H16L19.55,12M17.63,5.84C17.27,5.33 16.67,5 16,5H5A2,2 0 0,0 3,7V17A2,2 0 0,0 5,19H16C16.67,19 17.27,18.66 17.63,18.15L22,12L17.63,5.84Z" /></svg>`, labelOutline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16,17H5V7H16L19.55,12M17.63,5.84C17.27,5.33 16.67,5 16,5H5A2,2 0 0,0 3,7V17A2,2 0 0,0 5,19H16C16.67,19 17.27,18.66 17.63,18.15L22,12L17.63,5.84Z" /></svg>',
paletteOutline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2C17.5,2 22,6 22,11A6,6 0 0,1 16,17H14.2C13.9,17 13.7,17.2 13.7,17.5C13.7,17.6 13.8,17.7 13.8,17.8C14.2,18.3 14.4,18.9 14.4,19.5C14.5,20.9 13.4,22 12,22M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C12.3,20 12.5,19.8 12.5,19.5C12.5,19.3 12.4,19.2 12.4,19.1C12,18.6 11.8,18.1 11.8,17.5C11.8,16.1 12.9,15 14.3,15H16A4,4 0 0,0 20,11C20,7.1 16.4,4 12,4M6.5,10C7.3,10 8,10.7 8,11.5C8,12.3 7.3,13 6.5,13C5.7,13 5,12.3 5,11.5C5,10.7 5.7,10 6.5,10M9.5,6C10.3,6 11,6.7 11,7.5C11,8.3 10.3,9 9.5,9C8.7,9 8,8.3 8,7.5C8,6.7 8.7,6 9.5,6M14.5,6C15.3,6 16,6.7 16,7.5C16,8.3 15.3,9 14.5,9C13.7,9 13,8.3 13,7.5C13,6.7 13.7,6 14.5,6M17.5,10C18.3,10 19,10.7 19,11.5C19,12.3 18.3,13 17.5,13C16.7,13 16,12.3 16,11.5C16,10.7 16.7,10 17.5,10Z" /></svg>`, paletteOutline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2C17.5,2 22,6 22,11A6,6 0 0,1 16,17H14.2C13.9,17 13.7,17.2 13.7,17.5C13.7,17.6 13.8,17.7 13.8,17.8C14.2,18.3 14.4,18.9 14.4,19.5C14.5,20.9 13.4,22 12,22M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C12.3,20 12.5,19.8 12.5,19.5C12.5,19.3 12.4,19.2 12.4,19.1C12,18.6 11.8,18.1 11.8,17.5C11.8,16.1 12.9,15 14.3,15H16A4,4 0 0,0 20,11C20,7.1 16.4,4 12,4M6.5,10C7.3,10 8,10.7 8,11.5C8,12.3 7.3,13 6.5,13C5.7,13 5,12.3 5,11.5C5,10.7 5.7,10 6.5,10M9.5,6C10.3,6 11,6.7 11,7.5C11,8.3 10.3,9 9.5,9C8.7,9 8,8.3 8,7.5C8,6.7 8.7,6 9.5,6M14.5,6C15.3,6 16,6.7 16,7.5C16,8.3 15.3,9 14.5,9C13.7,9 13,8.3 13,7.5C13,6.7 13.7,6 14.5,6M17.5,10C18.3,10 19,10.7 19,11.5C19,12.3 18.3,13 17.5,13C16.7,13 16,12.3 16,11.5C16,10.7 16.7,10 17.5,10Z" /></svg>',
queryStats: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m105-233-65-47 200-320 120 140 160-260 109 163q-23 1-43.5 5.5T545-539l-22-33-152 247-121-141-145 233ZM863-40 738-165q-20 14-44.5 21t-50.5 7q-75 0-127.5-52.5T463-317q0-75 52.5-127.5T643-497q75 0 127.5 52.5T823-317q0 26-7 50.5T795-221L920-97l-57 57ZM643-217q42 0 71-29t29-71q0-42-29-71t-71-29q-42 0-71 29t-29 71q0 42 29 71t71 29Zm89-320q-19-8-39.5-13t-42.5-6l205-324 65 47-188 296Z"/></svg>`, queryStats: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m105-233-65-47 200-320 120 140 160-260 109 163q-23 1-43.5 5.5T545-539l-22-33-152 247-121-141-145 233ZM863-40 738-165q-20 14-44.5 21t-50.5 7q-75 0-127.5-52.5T463-317q0-75 52.5-127.5T643-497q75 0 127.5 52.5T823-317q0 26-7 50.5T795-221L920-97l-57 57ZM643-217q42 0 71-29t29-71q0-42-29-71t-71-29q-42 0-71 29t-29 71q0 42 29 71t71 29Zm89-320q-19-8-39.5-13t-42.5-6l205-324 65 47-188 296Z"/></svg>',
security: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,12H19C18.47,16.11 15.72,19.78 12,20.92V12H5V6.3L12,3.19M12,1L3,5V11C3,16.55 6.84,21.73 12,23C17.16,21.73 21,16.55 21,11V5L12,1Z" /></svg>`, security: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,12H19C18.47,16.11 15.72,19.78 12,20.92V12H5V6.3L12,3.19M12,1L3,5V11C3,16.55 6.84,21.73 12,23C17.16,21.73 21,16.55 21,11V5L12,1Z" /></svg>',
sync: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,18A6,6 0 0,1 6,12C6,11 6.25,10.03 6.7,9.2L5.24,7.74C4.46,8.97 4,10.43 4,12A8,8 0 0,0 12,20V23L16,19L12,15M12,4V1L8,5L12,9V6A6,6 0 0,1 18,12C18,13 17.75,13.97 17.3,14.8L18.76,16.26C19.54,15.03 20,13.57 20,12A8,8 0 0,0 12,4Z" /></svg>`, sync: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,18A6,6 0 0,1 6,12C6,11 6.25,10.03 6.7,9.2L5.24,7.74C4.46,8.97 4,10.43 4,12A8,8 0 0,0 12,20V23L16,19L12,15M12,4V1L8,5L12,9V6A6,6 0 0,1 18,12C18,13 17.75,13.97 17.3,14.8L18.76,16.26C19.54,15.03 20,13.57 20,12A8,8 0 0,0 12,4Z" /></svg>',
}; }
const navigationMappings = { interface Navigation {
name: string
icon?: string
dependsOn?: string
}
const navigationMappings: Record<string, Navigation> = {
// Main menus // Main menus
main_library: { name: "Library", icon: iconMappings["bookmarkBoxOutline"] }, "main_library": { name: "Library", icon: iconMappings.bookmarkBoxOutline },
main_updates: { name: "Updates", icon: iconMappings["alertDecagramOutline"] }, "main_updates": { name: "Updates", icon: iconMappings.alertDecagramOutline },
main_history: { name: "History", icon: iconMappings["history"] }, "main_history": { name: "History", icon: iconMappings.history },
main_browse: { name: "Browse", icon: iconMappings["compassOutline"] }, "main_browse": { name: "Browse", icon: iconMappings.compassOutline },
main_more: { name: "More", icon: iconMappings["dotsHorizontal"] }, "main_more": { name: "More", icon: iconMappings.dotsHorizontal },
// Browse menu // Browse menu
sources: { name: "Sources", dependsOn: "main_browse" }, "sources": { name: "Sources", dependsOn: "main_browse" },
extensions: { name: "Extensions", dependsOn: "main_browse" }, "extensions": { name: "Extensions", dependsOn: "main_browse" },
migrate: { name: "Migrate", dependsOn: "main_browse" }, "migrate": { name: "Migrate", dependsOn: "main_browse" },
// More menu // More menu
"downloaded-only": { name: "Downloaded only", icon: iconMappings["cloudOffOutline"], dependsOn: "main_more" }, "downloaded-only": { name: "Downloaded only", icon: iconMappings.cloudOffOutline, dependsOn: "main_more" },
"incognito-mode": { name: "Incognito mode", icon: iconMappings["glasses"], dependsOn: "main_more" }, "incognito-mode": { name: "Incognito mode", icon: iconMappings.glasses, dependsOn: "main_more" },
"download-queue": { name: "Download queue", icon: iconMappings["downloadOutline"], dependsOn: "main_more" }, "download-queue": { name: "Download queue", icon: iconMappings.downloadOutline, dependsOn: "main_more" },
categories: { name: "Categories", icon: iconMappings["labelOutline"], dependsOn: "main_more" }, "categories": { name: "Categories", icon: iconMappings.labelOutline, dependsOn: "main_more" },
statistics: { name: "Statistics", icon: iconMappings["queryStats"], dependsOn: "main_more" }, "statistics": { name: "Statistics", icon: iconMappings.queryStats, dependsOn: "main_more" },
"backup-and-restore": { name: "Backup and restore", icon: iconMappings["backupRestore"], dependsOn: "main_more" }, "backup-and-restore": { name: "Backup and restore", icon: iconMappings.backupRestore, dependsOn: "main_more" },
settings: { name: "Settings", icon: iconMappings["cog"], dependsOn: "main_more" }, "settings": { name: "Settings", icon: iconMappings.cog, dependsOn: "main_more" },
about: { name: "About", icon: iconMappings["informationOutline"], dependsOn: "main_more" }, "about": { name: "About", icon: iconMappings.informationOutline, dependsOn: "main_more" },
help: { name: "Help", icon: iconMappings["helpCircleOutline"], dependsOn: "main_more" }, "help": { name: "Help", icon: iconMappings.helpCircleOutline, dependsOn: "main_more" },
// Settings submenu // Settings submenu
appearance: { name: "Appearance", icon: iconMappings["paletteOutline"], dependsOn: "settings" }, "appearance": { name: "Appearance", icon: iconMappings.paletteOutline, dependsOn: "settings" },
library: { name: "Library", icon: iconMappings["bookmarkBoxOutline"], dependsOn: "settings" }, "library": { name: "Library", icon: iconMappings.bookmarkBoxOutline, dependsOn: "settings" },
downloads: { name: "Downloads", icon: iconMappings["downloadOutline"], dependsOn: "settings" }, "downloads": { name: "Downloads", icon: iconMappings.downloadOutline, dependsOn: "settings" },
tracking: { name: "Tracking", icon: iconMappings["sync"], dependsOn: "settings" }, "tracking": { name: "Tracking", icon: iconMappings.sync, dependsOn: "settings" },
browse: { name: "Browse", icon: iconMappings["compassOutline"], dependsOn: "settings" }, "browse": { name: "Browse", icon: iconMappings.compassOutline, dependsOn: "settings" },
"security-and-privacy": { name: "Security and privacy", icon: iconMappings["security"], dependsOn: "settings" }, "security-and-privacy": { name: "Security and privacy", icon: iconMappings.security, dependsOn: "settings" },
reader: { name: "Reader", icon: iconMappings["bookOpenOutline"], dependsOn: "settings" }, "reader": { name: "Reader", icon: iconMappings.bookOpenOutline, dependsOn: "settings" },
advanced: { name: "Advanced", icon: iconMappings["codeTags"], dependsOn: "settings" }, "advanced": { name: "Advanced", icon: iconMappings.codeTags, dependsOn: "settings" },
}; }
function generateNavigationHtml(navKey) { function generateNavigationHtml(navKey: string) {
const navData = navigationMappings[navKey]; const navData = navigationMappings[navKey]
if (!navData) { if (!navData) {
return "<strong style='color:var(--vp-c-danger-1)'>Unsupported Navigation!</strong>"; return "<strong style='color:var(--vp-c-danger-1)'>Unsupported Navigation!</strong>"
} }
const { name, icon, dependsOn } = navData; const { name, icon, dependsOn } = navData
const iconHtml = icon ? icon : ""; const iconHtml = icon ?? ""
let html = `<span class='shortcode navigation ${navKey}'>${iconHtml}<span class="name">${name}</span></span>`; let html = `<span class='shortcode navigation ${navKey}'>${iconHtml}<span class="name">${name}</span></span>`
if (dependsOn) { if (dependsOn) {
html = `${generateNavigationHtml(dependsOn)} -> ${html}`; html = `${generateNavigationHtml(dependsOn)} -> ${html}`
} }
return html; return html
} }
const shortcodes = { const shortcodes = {
nav: { nav: {
render: function (attrs, env) { render({ to }) {
const { method, to } = attrs; return generateNavigationHtml(to)
return generateNavigationHtml(to);
}, },
}, },
}; }
export default shortcodes; export default shortcodes

View File

@ -1,7 +1,7 @@
import type { DefaultTheme } from "vitepress"; import type { DefaultTheme } from "vitepress"
import nav from "./navigation/navbar"; import nav from "./navigation/navbar"
import sidebar from "./navigation/sidebar"; import sidebar from "./navigation/sidebar"
const themeConfig: DefaultTheme.Config = { const themeConfig: DefaultTheme.Config = {
logo: { logo: {
@ -10,8 +10,8 @@ const themeConfig: DefaultTheme.Config = {
height: 24, height: 24,
}, },
nav: nav, nav,
sidebar: sidebar, sidebar,
outline: [2, 3], outline: [2, 3],
@ -47,7 +47,7 @@ const themeConfig: DefaultTheme.Config = {
], ],
footer: { footer: {
message: `<a href="https://www.apache.org/licenses/LICENSE-2.0" target="_blank">Open-source Apache Licensed</a> | <a href="/privacy/">Privacy policy</a> | Powered by <a target="_blank" href="https://www.netlify.com/">Netlify <img src="/img/netlify.svg" alt="Netlify Logo" height="12px" width="12px" style="display: inline-block"></a>`, message: "<a href=\"https://www.apache.org/licenses/LICENSE-2.0\" target=\"_blank\">Open-source Apache Licensed</a> | <a href=\"/privacy/\">Privacy policy</a> | Powered by <a target=\"_blank\" href=\"https://www.netlify.com/\">Netlify <img src=\"/img/netlify.svg\" alt=\"Netlify Logo\" height=\"12px\" width=\"12px\" style=\"display: inline-block\"></a>",
copyright: `Copyright © 2015 - ${new Date().getFullYear()} Javier Tomás`, copyright: `Copyright © 2015 - ${new Date().getFullYear()} Javier Tomás`,
}, },
@ -67,6 +67,6 @@ const themeConfig: DefaultTheme.Config = {
search: { search: {
provider: "local", provider: "local",
}, },
}; }
export default themeConfig; export default themeConfig

View File

@ -1,20 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, toRefs } from "vue"; import { computed, toRefs } from "vue"
import MarkdownIt from "markdown-it"; import MarkdownIt from "markdown-it"
import { data as release, type AppRelease } from "../data/release.data"; import { type AppRelease, data as release } from "../data/release.data"
import Contributors from "./Contributors.vue"; import Contributors from "./Contributors.vue"
const props = defineProps<{ type: keyof AppRelease }>(); const props = defineProps<{ type: keyof AppRelease }>()
const { type } = toRefs(props); const { type } = toRefs(props)
const md = new MarkdownIt(); const md = new MarkdownIt()
const changelog = computed(() => { const changelog = computed(() => {
const flavoredString = (release[type.value].body ?? "") const flavoredString = (release[type.value].body ?? "")
.replace(/(?<=\(|(, ))@(.*?)(?=\)|(, ))/g, "[@$2](https://github.com/$2)") .replace(/(?<=\(|(, ))@(.*?)(?=\)|(, ))/g, "[@$2](https://github.com/$2)")
.replace('https://github.com/tachiyomiorg/tachiyomi/releases', '/changelogs/'); .replace("https://github.com/tachiyomiorg/tachiyomi/releases", "/changelogs/")
return md.render(flavoredString); return md.render(flavoredString)
}) })
</script> </script>

View File

@ -1,26 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import MarkdownIt from "markdown-it"; import MarkdownIt from "markdown-it"
import { data as changelogs } from "../data/changelogs.data"; import { data as changelogs } from "../data/changelogs.data"
import Contributors from "./Contributors.vue"; import Contributors from "./Contributors.vue"
const md = new MarkdownIt(); const md = new MarkdownIt()
function renderMarkdown(string: string | null | undefined) { function renderMarkdown(string: string | null | undefined) {
const body = string ?? "No changelog provided."; const body = string ?? "No changelog provided."
const flavoredString = body const flavoredString = body
.split(/---\r\n\r\n### Checksums|---\r\n\r\nMD5/)[0] .split(/---\r\n\r\n### Checksums|---\r\n\r\nMD5/)[0]
.replace(/(?<=\(|(, ))@(.*?)(?=\)|(, ))/g, "[@$2](https://github.com/$2)") .replace(/(?<=\(|(, ))@(.*?)(?=\)|(, ))/g, "[@$2](https://github.com/$2)")
.replace(/#(\d+)/g, '[#$1](https://github.com/tachiyomiorg/tachiyomi/issues/$1)') .replace(/#(\d+)/g, "[#$1](https://github.com/tachiyomiorg/tachiyomi/issues/$1)")
.replace(/^Check out the .*past release notes.* if you're.*$/m, "") .replace(/^Check out the .*past release notes.* if you're.*$/m, "")
.replace(/https\:\/\/github.com\/tachiyomiorg\/tachiyomi\/releases\/tag\/(.*?)/g, "#$1") .replace(/https\:\/\/github.com\/tachiyomiorg\/tachiyomi\/releases\/tag\/(.*?)/g, "#$1")
.trim(); .trim()
return md.render(flavoredString); return md.render(flavoredString)
} }
const dateFormatter = new Intl.DateTimeFormat("en", { const dateFormatter = new Intl.DateTimeFormat("en", {
dateStyle: "medium", dateStyle: "medium",
}); })
</script> </script>
<template> <template>
@ -45,7 +45,7 @@ const dateFormatter = new Intl.DateTimeFormat("en", {
<time :datetime="release.published_at!"> <time :datetime="release.published_at!">
{{ dateFormatter.format(new Date(release.published_at!)) }} {{ dateFormatter.format(new Date(release.published_at!)) }}
</time> </time>
<div v-html="renderMarkdown(release.body)"></div> <div v-html="renderMarkdown(release.body)" />
<Contributors <Contributors
:body="release.body!" :body="release.body!"
:author="release.author.login" :author="release.author.login"

View File

@ -1,55 +1,54 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, toRefs } from "vue"; import { computed, ref, toRefs } from "vue"
const props = defineProps<{ body: string; author: string; tag: string; }>(); const props = defineProps<{ body: string; author: string; tag: string }>()
const { body, author, tag } = toRefs(props); const { body, author, tag } = toRefs(props)
function isHigherThan(tagName: string, reference: string) { function isHigherThan(tagName: string, reference: string) {
return reference.localeCompare(tagName, undefined, { numeric: true, sensitivity: "base" }) >= 0; return reference.localeCompare(tagName, undefined, { numeric: true, sensitivity: "base" }) >= 0
} }
const notMentioned = computed(() => { const notMentioned = computed(() => {
return isHigherThan("v0.8.5", tag.value) ? ['arkon'] : []; return isHigherThan("v0.8.5", tag.value) ? ["arkon"] : []
}); })
const nonExistent = ref<string[]>([]) const nonExistent = ref<string[]>([])
const contributors = computed(() => { const contributors = computed(() => {
const list = [...body.value.matchAll(/(?<=\(|(, ))@(.*?)(?=\)|(, ))/g)] const list = [...body.value.matchAll(/(?<=\(|(, ))@(.*?)(?=\)|(, ))/g)]
.map((match) => match[2]) .map((match) => match[2])
const uncredited = author.value.includes('[bot]') const uncredited = author.value.includes("[bot]")
? notMentioned.value ? notMentioned.value
: [author.value, ...notMentioned.value]; : [author.value, ...notMentioned.value]
return [...new Set([...uncredited, ...list])].filter((user) => !nonExistent.value.includes(user)); return [...new Set([...uncredited, ...list])].filter((user) => !nonExistent.value.includes(user))
}); })
// @ts-expect-error
const listFormatter = new Intl.ListFormat("en", { const listFormatter = new Intl.ListFormat("en", {
style: "long", style: "long",
type: "conjunction", type: "conjunction",
}); })
const contributorsText = computed(() => { const contributorsText = computed(() => {
if (contributors.value.length <= 3) { if (contributors.value.length <= 3) {
return listFormatter.format(contributors.value); return listFormatter.format(contributors.value)
} }
return listFormatter.format([ return listFormatter.format([
...contributors.value.slice(0, 2), ...contributors.value.slice(0, 2),
`${contributors.value.length - 2} other contributors` `${contributors.value.length - 2} other contributors`,
]); ])
}); })
function addToNonExistent(user: string) { function addToNonExistent(user: string) {
if (!nonExistent.value.includes(user)) { if (!nonExistent.value.includes(user)) {
nonExistent.value.push(user); nonExistent.value.push(user)
} }
} }
</script> </script>
<template> <template>
<div class="contributors" v-if="contributors.length > 0"> <div v-if="contributors.length > 0" class="contributors">
<h3>Contributors</h3> <h3>Contributors</h3>
<ul> <ul>
<li <li
@ -65,9 +64,9 @@ function addToNonExistent(user: string) {
<img <img
:src="`https://github.com/${contributor}.png?size=32`" :src="`https://github.com/${contributor}.png?size=32`"
:alt="`@${contributor} profile picture`" :alt="`@${contributor} profile picture`"
@error="addToNonExistent(contributor)"
loading="lazy" loading="lazy"
class="avatar" class="avatar"
@error="addToNonExistent(contributor)"
> >
</a> </a>
</li> </li>

View File

@ -1,13 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from "vue"; import { computed } from "vue"
import { type DefaultTheme, useData } from "vitepress"; import { type DefaultTheme, useData } from "vitepress"
import { data as release } from "../data/release.data"; import { data as release } from "../data/release.data"
import VPNavBarMenuLink from "vitepress/dist/client/theme-default/components/VPNavBarMenuLink.vue"; import VPNavBarMenuLink from "vitepress/dist/client/theme-default/components/VPNavBarMenuLink.vue"
import VPNavBarMenuGroup from "vitepress/dist/client/theme-default/components/VPNavBarMenuGroup.vue"; import VPNavBarMenuGroup from "vitepress/dist/client/theme-default/components/VPNavBarMenuGroup.vue"
const { theme } = useData<DefaultTheme.Config>(); const { theme } = useData<DefaultTheme.Config>()
/** /**
* Workaround to use the release data directly while the sidebar * Workaround to use the release data directly while the sidebar
@ -19,14 +19,14 @@ const nav = computed(() => {
return item return item
} }
const appVersion = release.stable.tag_name.substring(1); const appVersion = release.stable.tag_name.substring(1)
return <DefaultTheme.NavItemWithChildren> { return <DefaultTheme.NavItemWithChildren> {
...item, ...item,
text: item.text === "{app_version}" ? appVersion : item.text, text: item.text === "{app_version}" ? appVersion : item.text,
items: (item as DefaultTheme.NavItemWithChildren).items.map((child) => { items: (item as DefaultTheme.NavItemWithChildren).items.map((child) => {
if (!("link" in child)) { if (!("link" in child)) {
return child; return child
} }
return <DefaultTheme.NavItemWithLink> { return <DefaultTheme.NavItemWithLink> {
@ -35,7 +35,7 @@ const nav = computed(() => {
} }
}), }),
} }
}); })
}) })
</script> </script>

View File

@ -1,13 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from "vue"; import { computed } from "vue"
import { type DefaultTheme, useData } from "vitepress"; import { type DefaultTheme, useData } from "vitepress"
import { data as release } from "../data/release.data"; import { data as release } from "../data/release.data"
import VPNavScreenMenuLink from "vitepress/dist/client/theme-default/components/VPNavScreenMenuLink.vue"; import VPNavScreenMenuLink from "vitepress/dist/client/theme-default/components/VPNavScreenMenuLink.vue"
import VPNavScreenMenuGroup from "vitepress/dist/client/theme-default/components/VPNavScreenMenuGroup.vue"; import VPNavScreenMenuGroup from "vitepress/dist/client/theme-default/components/VPNavScreenMenuGroup.vue"
const { theme } = useData<DefaultTheme.Config>(); const { theme } = useData<DefaultTheme.Config>()
/** /**
* Workaround to use the release data directly while the sidebar * Workaround to use the release data directly while the sidebar
@ -19,14 +19,14 @@ const nav = computed(() => {
return item return item
} }
const appVersion = release.stable.tag_name.substring(1); const appVersion = release.stable.tag_name.substring(1)
return <DefaultTheme.NavItemWithChildren> { return <DefaultTheme.NavItemWithChildren> {
...item, ...item,
text: item.text === "{app_version}" ? appVersion : item.text, text: item.text === "{app_version}" ? appVersion : item.text,
items: (item as DefaultTheme.NavItemWithChildren).items.map((child) => { items: (item as DefaultTheme.NavItemWithChildren).items.map((child) => {
if (!("link" in child)) { if (!("link" in child)) {
return child; return child
} }
return <DefaultTheme.NavItemWithLink> { return <DefaultTheme.NavItemWithLink> {
@ -35,7 +35,7 @@ const nav = computed(() => {
} }
}), }),
} }
}); })
}) })
</script> </script>

View File

@ -1,18 +1,18 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from "vue"; import { computed } from "vue"
import { data as release } from "../data/release.data"; import { data as release } from "../data/release.data"
const downloadInformation = computed(() => ({ const downloadInformation = computed(() => ({
preview: { preview: {
tagName: release.preview.tag_name ?? "r0000", tagName: release.preview.tag_name ?? "r0000",
asset: (release.preview.assets ?? []) asset: (release.preview.assets ?? [])
.find(a => /^tachiyomi-r\d{4,}.apk/.test(a.name)), .find((a) => /^tachiyomi-r\d{4,}.apk/.test(a.name)),
}, },
stable: { stable: {
tagName: release.stable.tag_name?.slice(1) ?? "0.00.0", tagName: release.stable.tag_name?.slice(1) ?? "0.00.0",
asset: (release.stable.assets ?? []) asset: (release.stable.assets ?? [])
.find(a => /^tachiyomi-v\d+\.\d+\.\d+.apk/.test(a.name)), .find((a) => /^tachiyomi-v\d+\.\d+\.\d+.apk/.test(a.name)),
} },
})) }))
</script> </script>

View File

@ -1,86 +1,85 @@
<script setup lang="ts"> <script setup lang="ts">
import { toRefs } from "vue"; import { toRefs } from "vue"
import { langName, simpleLangName } from "../../../config/scripts/languages";
import type { Extension } from "../../queries/useExtensionsRepositoryQuery";
import { import {
ElForm, ElForm,
ElFormItem, ElFormItem,
ElInput, ElInput,
ElSelect,
ElOption, ElOption,
ElRadioGroup,
ElRadio, ElRadio,
} from "element-plus"; ElRadioGroup,
ElSelect,
} from "element-plus"
import { langName, simpleLangName } from "../../../config/scripts/languages"
import type { Extension } from "../../queries/useExtensionsRepositoryQuery"
export type Nsfw = "Show all" | "NSFW" | "SFW"; export type Nsfw = "Show all" | "NSFW" | "SFW"
export type Sort = "Ascending" | "Descending"; export type Sort = "Ascending" | "Descending"
const props = defineProps<{ const props = defineProps<{
extensions: Extension[][]; extensions: Extension[][]
search: string; search: string
lang: string[]; lang: string[]
nsfw: Nsfw; nsfw: Nsfw
sort: Sort; sort: Sort
}>(); }>()
const { extensions } = toRefs(props);
defineEmits<{ defineEmits<{
(e: 'update:search', search: string): void; (e: "update:search", search: string): void
(e: 'update:lang', lang: string[]): void, (e: "update:lang", lang: string[]): void
(e: 'update:nsfw', nsfw: Nsfw): void, (e: "update:nsfw", nsfw: Nsfw): void
(e: 'update:sort', sort: Sort): void, (e: "update:sort", sort: Sort): void
}>(); }>()
const { extensions } = toRefs(props)
</script> </script>
<template> <template>
<div class="filters-list"> <div class="filters-list">
<el-form label-width="120px"> <ElForm label-width="120px">
<el-form-item label="Search:"> <ElFormItem label="Search:">
<el-input <ElInput
:model-value="search" :model-value="search"
placeholder="Search extensions by name or ID..." placeholder="Search extensions by name or ID..."
clearable clearable
@update:model-value="$emit('update:search', $event)" @update:model-value="$emit('update:search', $event)"
/> />
</el-form-item> </ElFormItem>
<el-form-item label="Languages:"> <ElFormItem label="Languages:">
<el-select <ElSelect
:model-value="lang" :model-value="lang"
placeholder="Show specific languages..." placeholder="Show specific languages..."
multiple multiple
clearable clearable
@update:model-value="$emit('update:lang', $event)" @update:model-value="$emit('update:lang', $event)"
> >
<el-option <ElOption
v-for="[group] in extensions" v-for="[group] in extensions"
:key="group.lang" :key="group.lang"
:label="group.lang === 'en' ? simpleLangName(group.lang) : langName(group.lang)" :label="group.lang === 'en' ? simpleLangName(group.lang) : langName(group.lang)"
:value="group.lang" :value="group.lang"
/> />
</el-select> </ElSelect>
</el-form-item> </ElFormItem>
<el-form-item label="Sort by:"> <ElFormItem label="Sort by:">
<el-radio-group <ElRadioGroup
:model-value="sort" :model-value="sort"
@update:model-value="$emit('update:sort', $event)" @update:model-value="$emit('update:sort', $event)"
> >
<el-radio label="Ascending"></el-radio> <ElRadio label="Ascending" />
<el-radio label="Descending"></el-radio> <ElRadio label="Descending" />
</el-radio-group> </ElRadioGroup>
</el-form-item> </ElFormItem>
<el-form-item label="Display mode:"> <ElFormItem label="Display mode:">
<el-radio-group <ElRadioGroup
:model-value="nsfw" :model-value="nsfw"
@update:model-value="$emit('update:nsfw', $event)" @update:model-value="$emit('update:nsfw', $event)"
> >
<el-radio label="NSFW"></el-radio> <ElRadio label="NSFW" />
<el-radio label="SFW"></el-radio> <ElRadio label="SFW" />
<el-radio label="Show all"></el-radio> <ElRadio label="Show all" />
</el-radio-group> </ElRadioGroup>
</el-form-item> </ElFormItem>
</el-form> </ElForm>
</div> </div>
</template> </template>

View File

@ -1,19 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, toRefs } from "vue"; import { computed, toRefs } from "vue"
import { langName, simpleLangName } from "../../../config/scripts/languages"; import { langName, simpleLangName } from "../../../config/scripts/languages"
import ExtensionItem from "./ExtensionItem.vue"; import type { Extension } from "../../queries/useExtensionsRepositoryQuery"
import type { Extension } from "../../queries/useExtensionsRepositoryQuery"; import ExtensionItem from "./ExtensionItem.vue"
const props = defineProps<{ list: Extension[]; totalCount: number }>(); const props = defineProps<{ list: Extension[]; totalCount: number }>()
const { list } = toRefs(props); const { list } = toRefs(props)
const groupName = computed(() => { const groupName = computed(() => {
const firstItem = list.value[0]; const firstItem = list.value[0]
return firstItem.lang === "en" return firstItem.lang === "en"
? simpleLangName(firstItem.lang) ? simpleLangName(firstItem.lang)
: langName(firstItem.lang); : langName(firstItem.lang)
}); })
</script> </script>
<template> <template>

View File

@ -1,30 +1,30 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, toRefs } from "vue"; import { computed, toRefs } from "vue"
import type { Extension } from "../../queries/useExtensionsRepositoryQuery"; import type { Extension } from "../../queries/useExtensionsRepositoryQuery"
const props = defineProps<{ item: Extension }>(); const props = defineProps<{ item: Extension }>()
const { item } = toRefs(props); const { item } = toRefs(props)
const pkgId = computed(() => { const pkgId = computed(() => {
return item.value.pkg.replace("eu.kanade.tachiyomi.extension.", ""); return item.value.pkg.replace("eu.kanade.tachiyomi.extension.", "")
}); })
const pkgName = computed(() => item.value.name.split(": ")[1]); const pkgName = computed(() => item.value.name.split(": ")[1])
const pkgIsNsfw = computed(() => item.value.nsfw === 1); const pkgIsNsfw = computed(() => item.value.nsfw === 1)
const iconUrl = computed(() => { const iconUrl = computed(() => {
return `https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/icon/${item.value.pkg}.png`; return `https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/icon/${item.value.pkg}.png`
}); })
const apkUrl = computed(() => { const apkUrl = computed(() => {
return `https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/apk/${item.value.apk}`; return `https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/apk/${item.value.apk}`
}); })
</script> </script>
<template> <template>
<div class="extension"> <div class="extension">
<a :href="`#${pkgId}`" class="anchor" aria-hidden="true" @click.stop>#</a> <a :href="`#${pkgId}`" class="anchor" aria-hidden="true" @click.stop>#</a>
<img class="extension-icon" :src="iconUrl" loading="lazy" width="42" height="42" /> <img class="extension-icon" :src="iconUrl" loading="lazy" width="42" height="42">
<div class="extension-text"> <div class="extension-text">
<div class="upper"> <div class="upper">
{{ pkgName }} {{ pkgName }}

View File

@ -1,14 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, toRefs } from "vue"; import { computed, toRefs } from "vue"
import ExtensionGroup from "./ExtensionGroup.vue"; import type { Extension } from "../../queries/useExtensionsRepositoryQuery"
import type { Extension } from "../../queries/useExtensionsRepositoryQuery"; import ExtensionGroup from "./ExtensionGroup.vue"
const props = defineProps<{ extensions: Extension[][] }>(); const props = defineProps<{ extensions: Extension[][] }>()
const { extensions } = toRefs(props); const { extensions } = toRefs(props)
const totalCount = computed(() => { const totalCount = computed(() => {
return extensions.value.reduce((sum, item) => sum + item.length, 0); return extensions.value.reduce((sum, item) => sum + item.length, 0)
}); })
</script> </script>
<template> <template>

View File

@ -1,117 +1,117 @@
<script setup lang="ts"> <script setup lang="ts">
import groupBy from "lodash.groupby"; import groupBy from "lodash.groupby"
import { ElLoading } from "element-plus"; import { ElLoading } from "element-plus"
import { simpleLangName } from "../../../config/scripts/languages"; import { computed, nextTick, onMounted, reactive, ref, watch } from "vue"
import ExtensionFilters from "./ExtensionFilters.vue"; import { simpleLangName } from "../../../config/scripts/languages"
import ExtensionList from "./ExtensionList.vue"; import useExtensionsRepositoryQuery from "../../queries/useExtensionsRepositoryQuery"
import useExtensionsRepositoryQuery from "../../queries/useExtensionsRepositoryQuery"; import type { Extension } from "../../queries/useExtensionsRepositoryQuery"
import { computed, nextTick, onMounted, onUpdated, reactive, ref, watch } from 'vue'; import ExtensionFilters from "./ExtensionFilters.vue"
import type { Extension } from "../../queries/useExtensionsRepositoryQuery"; import ExtensionList from "./ExtensionList.vue"
import type { Nsfw, Sort } from "./ExtensionFilters.vue"; import type { Nsfw, Sort } from "./ExtensionFilters.vue"
const { data: extensions, isLoading } = useExtensionsRepositoryQuery({ const { data: extensions, isLoading } = useExtensionsRepositoryQuery({
select: (response) => { select: (response) => {
const values: Extension[][] = Object.values(groupBy(response, "lang")); const values: Extension[][] = Object.values(groupBy(response, "lang"))
values.sort(languageComparator) values.sort(languageComparator)
return values return values
}, },
}); })
const filters = reactive({ const filters = reactive({
search: "", search: "",
lang: [] as string[], lang: [] as string[],
nsfw: "Show all" as Nsfw, nsfw: "Show all" as Nsfw,
sort: "Ascending" as Sort, sort: "Ascending" as Sort,
}); })
function languageComparator(a: Extension[], b: Extension[]) { function languageComparator(a: Extension[], b: Extension[]) {
const langA = simpleLangName(a[0].lang); const langA = simpleLangName(a[0].lang)
const langB = simpleLangName(b[0].lang); const langB = simpleLangName(b[0].lang)
if (langA === "All" && langB === "English") { if (langA === "All" && langB === "English") {
return -1; return -1
} }
if (langA === "English" && langB === "All") { if (langA === "English" && langB === "All") {
return 1; return 1
} }
if (langA === "English") { if (langA === "English") {
return -1; return -1
} }
if (langB === "English") { if (langB === "English") {
return 1; return 1
} }
if (langA < langB) { if (langA < langB) {
return -1; return -1
} }
if (langA > langB) { if (langA > langB) {
return 1; return 1
} }
return 0; return 0
} }
const filteredExtensions = computed(() => { const filteredExtensions = computed(() => {
const filtered: Extension[][] = []; const filtered: Extension[][] = []
for (const group of (extensions.value ?? [])) { for (const group of (extensions.value ?? [])) {
let filteredGroup = filters.lang.length let filteredGroup = filters.lang.length
? (filters.lang.includes(group[0].lang) ? group : []) ? (filters.lang.includes(group[0].lang) ? group : [])
: group; : group
if (filters.search) { if (filters.search) {
filteredGroup = filteredGroup.filter( filteredGroup = filteredGroup.filter(
(ext) => (ext) =>
ext.name.toLowerCase().includes(filters.search.toLowerCase()) || ext.name.toLowerCase().includes(filters.search.toLowerCase())
ext.sources.some((source) => source.id.includes(filters.search)) || ext.sources.some((source) => source.id.includes(filters.search)),
); )
} }
filteredGroup = filteredGroup.filter((ext) => filteredGroup = filteredGroup.filter((ext) =>
filters.nsfw === "Show all" ? true : ext.nsfw === (filters.nsfw === "NSFW" ? 1 : 0) filters.nsfw === "Show all" ? true : ext.nsfw === (filters.nsfw === "NSFW" ? 1 : 0),
); )
if (filters.sort && filters.sort === "Descending") { if (filters.sort && filters.sort === "Descending") {
filteredGroup = filteredGroup.reverse(); filteredGroup = filteredGroup.reverse()
} }
if (filteredGroup.length) { if (filteredGroup.length) {
filtered.push(filteredGroup); filtered.push(filteredGroup)
} }
} }
return filtered; return filtered
}); })
const loadingInstance = ref<ReturnType<typeof ElLoading['service']>>(); const loadingInstance = ref<ReturnType<typeof ElLoading["service"]>>()
onMounted(() => { onMounted(() => {
loadingInstance.value = ElLoading.service({ loadingInstance.value = ElLoading.service({
target: ".extensions", target: ".extensions",
fullscreen: false, fullscreen: false,
background: "transparent", background: "transparent",
}); })
}) })
watch(extensions, async () => { watch(extensions, async () => {
if (window.location.hash) { if (window.location.hash) {
await nextTick() await nextTick()
document.getElementById(window.location.hash.substring(1)) document.getElementById(window.location.hash.substring(1))
?.scrollIntoView({ behavior: 'smooth' }); ?.scrollIntoView({ behavior: "smooth" })
} }
}); })
watch([isLoading, loadingInstance], async ([newIsLoading]) => { watch([isLoading, loadingInstance], async ([newIsLoading]) => {
if (!newIsLoading) { if (!newIsLoading) {
loadingInstance.value?.close(); loadingInstance.value?.close()
} }
}); })
</script> </script>
<template> <template>
<ExtensionFilters <ExtensionFilters
:extensions="extensions ?? []"
v-model:search="filters.search" v-model:search="filters.search"
v-model:lang="filters.lang" v-model:lang="filters.lang"
v-model:nsfw="filters.nsfw" v-model:nsfw="filters.nsfw"
v-model:sort="filters.sort" v-model:sort="filters.sort"
:extensions="extensions ?? []"
/> />
<div class="extensions"> <div class="extensions">
<ExtensionList v-if="!isLoading" :extensions="filteredExtensions" /> <ExtensionList v-if="!isLoading" :extensions="filteredExtensions" />

View File

@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { data as newsList } from "../data/news.data"; import { IconChevronRight } from "@iconify-prerendered/vue-mdi"
import { IconChevronRight } from "@iconify-prerendered/vue-mdi"; import { data as newsList } from "../data/news.data"
const dateFormatter = new Intl.DateTimeFormat("en", { dateStyle: "medium" }); const dateFormatter = new Intl.DateTimeFormat("en", { dateStyle: "medium" })
</script> </script>
<template> <template>

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
defineProps<{ title: string; description?: string; dir?: string }>(); defineProps<{ title: string; description?: string; dir?: string }>()
</script> </script>
<template> <template>
@ -11,17 +11,25 @@
<div tw="w-full flex justify-between items-center text-4xl font-medium"> <div tw="w-full flex justify-between items-center text-4xl font-medium">
<div tw="flex items-center"> <div tw="flex items-center">
<svg width="64" height="64" viewBox="0 0 288 288" preserveAspectRatio="xMidYMid meet" fill="#8995FF"><path d="M141.2 36.7l-18.3.3.8 9.8c.4 5.3.8 11.9.8 14.7v5h-41-41l.3 17.9.3 17.9 6.7-.7c15.2-1.4 101.5-1.8 146.2-.7l48 1.6c1.3.4 1.5-2 1.5-17.8V66.5l-38.3.4c-21 .2-39.8 0-41.8-.3l-3.5-.7.3-15c.3-12.8.1-14.9-1.2-14.7-.8.1-9.7.4-19.8.5zm-56.7 76.9c-12.8 5-16 6.7-15.8 8.1.1 1 2.2 7.3 4.7 14 5.8 15.3 12.4 38.4 16.6 57.8l3.5 15.3c.2.2 8.3-2.5 18.2-6l17.9-6.3-1.2-6c-3.5-16.8-24.8-83.6-26.7-83.4-.7.1-8.4 3-17.2 6.5zm93.6 10.1c-10.4 41.7-22.9 83.2-27.1 90.1l-1.9 3.1-17.3.3c-20 .3-91.3-.9-94.3-1.6-1.9-.5-2 0-2 18v18.6l5-.6c2.8-.3 51.8-.9 109-1.2l104-.7v-17.6-17.6l-8.5.7c-4.7.3-19.5.7-32.9.7-19.1.1-24.2-.2-23.8-1.2.3-.6 2.2-5 4.2-9.7 6.5-15.2 29.6-86.3 28.4-87.4-.4-.4-32.6-9.4-36.5-10.3-2-.4-2.4.7-6.3 16.4z" /></svg> <svg width="64" height="64" viewBox="0 0 288 288" preserveAspectRatio="xMidYMid meet" fill="#8995FF"><path d="M141.2 36.7l-18.3.3.8 9.8c.4 5.3.8 11.9.8 14.7v5h-41-41l.3 17.9.3 17.9 6.7-.7c15.2-1.4 101.5-1.8 146.2-.7l48 1.6c1.3.4 1.5-2 1.5-17.8V66.5l-38.3.4c-21 .2-39.8 0-41.8-.3l-3.5-.7.3-15c.3-12.8.1-14.9-1.2-14.7-.8.1-9.7.4-19.8.5zm-56.7 76.9c-12.8 5-16 6.7-15.8 8.1.1 1 2.2 7.3 4.7 14 5.8 15.3 12.4 38.4 16.6 57.8l3.5 15.3c.2.2 8.3-2.5 18.2-6l17.9-6.3-1.2-6c-3.5-16.8-24.8-83.6-26.7-83.4-.7.1-8.4 3-17.2 6.5zm93.6 10.1c-10.4 41.7-22.9 83.2-27.1 90.1l-1.9 3.1-17.3.3c-20 .3-91.3-.9-94.3-1.6-1.9-.5-2 0-2 18v18.6l5-.6c2.8-.3 51.8-.9 109-1.2l104-.7v-17.6-17.6l-8.5.7c-4.7.3-19.5.7-32.9.7-19.1.1-24.2-.2-23.8-1.2.3-.6 2.2-5 4.2-9.7 6.5-15.2 29.6-86.3 28.4-87.4-.4-.4-32.6-9.4-36.5-10.3-2-.4-2.4.7-6.3 16.4z" /></svg>
<div tw="text-slate-900 ml-2 mt-1 font-semibold">Tachiyomi</div> <div tw="text-slate-900 ml-2 mt-1 font-semibold">
Tachiyomi
</div>
</div> </div>
<div v-if="dir" tw="flex items-center text-slate-600"> <div v-if="dir" tw="flex items-center text-slate-600">
<div v-if="dir" tw="text-4xl font-semibold mr-2">{{ dir }}</div> <div v-if="dir" tw="text-4xl font-semibold mr-2">
<svg v-if="dir == 'FAQ'" width="48" height="48" viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" fill="currentColor"><path d="M18,15H6L2,19V3A1,1 0 0,1 3,2H18A1,1 0 0,1 19,3V14A1,1 0 0,1 18,15M23,9V23L19,19H8A1,1 0 0,1 7,18V17H21V8H22A1,1 0 0,1 23,9M8.19,4C7.32,4 6.62,4.2 6.08,4.59C5.56,5 5.3,5.57 5.31,6.36L5.32,6.39H7.25C7.26,6.09 7.35,5.86 7.53,5.7C7.71,5.55 7.93,5.47 8.19,5.47C8.5,5.47 8.76,5.57 8.94,5.75C9.12,5.94 9.2,6.2 9.2,6.5C9.2,6.82 9.13,7.09 8.97,7.32C8.83,7.55 8.62,7.75 8.36,7.91C7.85,8.25 7.5,8.55 7.31,8.82C7.11,9.08 7,9.5 7,10H9C9,9.69 9.04,9.44 9.13,9.26C9.22,9.08 9.39,8.9 9.64,8.74C10.09,8.5 10.46,8.21 10.75,7.81C11.04,7.41 11.19,7 11.19,6.5C11.19,5.74 10.92,5.13 10.38,4.68C9.85,4.23 9.12,4 8.19,4M7,11V13H9V11H7M13,13H15V11H13V13M13,4V10H15V4H13Z" /></svg> {{ dir }}
<svg v-if="dir == 'Guide'" width="48" height="48" viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" fill="currentColor"><path d="M12,3L1,9L12,15L21,10.09V17H23V9M5,13.18V17.18L12,21L19,17.18V13.18L12,17L5,13.18Z" /></svg> </div>
<svg v-if="dir === 'FAQ'" width="48" height="48" viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" fill="currentColor"><path d="M18,15H6L2,19V3A1,1 0 0,1 3,2H18A1,1 0 0,1 19,3V14A1,1 0 0,1 18,15M23,9V23L19,19H8A1,1 0 0,1 7,18V17H21V8H22A1,1 0 0,1 23,9M8.19,4C7.32,4 6.62,4.2 6.08,4.59C5.56,5 5.3,5.57 5.31,6.36L5.32,6.39H7.25C7.26,6.09 7.35,5.86 7.53,5.7C7.71,5.55 7.93,5.47 8.19,5.47C8.5,5.47 8.76,5.57 8.94,5.75C9.12,5.94 9.2,6.2 9.2,6.5C9.2,6.82 9.13,7.09 8.97,7.32C8.83,7.55 8.62,7.75 8.36,7.91C7.85,8.25 7.5,8.55 7.31,8.82C7.11,9.08 7,9.5 7,10H9C9,9.69 9.04,9.44 9.13,9.26C9.22,9.08 9.39,8.9 9.64,8.74C10.09,8.5 10.46,8.21 10.75,7.81C11.04,7.41 11.19,7 11.19,6.5C11.19,5.74 10.92,5.13 10.38,4.68C9.85,4.23 9.12,4 8.19,4M7,11V13H9V11H7M13,13H15V11H13V13M13,4V10H15V4H13Z" /></svg>
<svg v-else-if="dir === 'Guide'" width="48" height="48" viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" fill="currentColor"><path d="M12,3L1,9L12,15L21,10.09V17H23V9M5,13.18V17.18L12,21L19,17.18V13.18L12,17L5,13.18Z" /></svg>
</div> </div>
</div> </div>
<div tw="w-full pr-56 flex flex-col items-start justify-end"> <div tw="w-full pr-56 flex flex-col items-start justify-end">
<div tw="text-6xl font-bold text-slate-900">{{ title }}</div> <div tw="text-6xl font-bold text-slate-900">
<div v-if="description" tw="mt-2 text-4xl text-slate-600">{{ description }}</div> {{ title }}
</div>
<div v-if="description" tw="mt-2 text-4xl text-slate-600">
{{ description }}
</div>
</div> </div>
</div> </div>
<div tw="shrink-0 h-2 w-full flex" style="background-color: #8995ff;" /> <div tw="shrink-0 h-2 w-full flex" style="background-color: #8995ff;" />

View File

@ -1,15 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, toRefs } from "vue"; import { computed, toRefs } from "vue"
import moment from "moment"; import moment from "moment"
import { data as release, type AppRelease } from "../data/release.data"; import { type AppRelease, data as release } from "../data/release.data"
const props = defineProps<{ type: keyof AppRelease }>(); const props = defineProps<{ type: keyof AppRelease }>()
const { type } = toRefs(props); const { type } = toRefs(props)
const momentInfo = computed(() => ({ const momentInfo = computed(() => ({
relative: moment(release[type.value].published_at).fromNow(), relative: moment(release[type.value].published_at).fromNow(),
exact: moment(release[type.value].published_at).format("dddd, MMMM Do YYYY [at] HH:mm"), exact: moment(release[type.value].published_at).format("dddd, MMMM Do YYYY [at] HH:mm"),
iso: release[type.value].published_at, iso: release[type.value].published_at ?? undefined,
})) }))
</script> </script>

View File

@ -1,13 +1,13 @@
import { defineLoader } from "vitepress"; import { defineLoader } from "vitepress"
import { Octokit } from "@octokit/rest"; import { Octokit } from "@octokit/rest"
import type { GetResponseDataTypeFromEndpointMethod } from "@octokit/types"; import type { GetResponseDataTypeFromEndpointMethod } from "@octokit/types"
const octokit = new Octokit(); const octokit = new Octokit()
type GitHubReleaseList = GetResponseDataTypeFromEndpointMethod<typeof octokit.repos.listReleases>; type GitHubReleaseList = GetResponseDataTypeFromEndpointMethod<typeof octokit.repos.listReleases>
declare const data: GitHubReleaseList; declare const data: GitHubReleaseList
export { data }; export { data }
export default defineLoader({ export default defineLoader({
async load(): Promise<GitHubReleaseList> { async load(): Promise<GitHubReleaseList> {
@ -15,8 +15,8 @@ export default defineLoader({
owner: "tachiyomiorg", owner: "tachiyomiorg",
repo: "tachiyomi", repo: "tachiyomi",
per_page: 100, per_page: 100,
}); })
return releases; return releases
}, },
}); })

View File

@ -1,14 +1,14 @@
import { defineLoader, createContentLoader } from "vitepress"; import { createContentLoader } from "vitepress"
export interface News { export interface News {
title: string; title: string
description: string; description: string
date: string; date: string
url: string; url: string
} }
declare const data: News[]; declare const data: News[]
export { data }; export { data }
export default createContentLoader("news/*.md", { export default createContentLoader("news/*.md", {
excerpt: true, excerpt: true,
@ -22,8 +22,8 @@ export default createContentLoader("news/*.md", {
description: frontmatter.description, description: frontmatter.description,
date: frontmatter.date, date: frontmatter.date,
url, url,
} },
) )
.sort((a, b) => b.date.localeCompare(a.date)); .sort((a, b) => b.date.localeCompare(a.date))
} },
}); })

View File

@ -1,31 +1,31 @@
import { defineLoader } from "vitepress"; import { defineLoader } from "vitepress"
import { Octokit } from "@octokit/rest"; import { Octokit } from "@octokit/rest"
import type { GetResponseDataTypeFromEndpointMethod } from "@octokit/types"; import type { GetResponseDataTypeFromEndpointMethod } from "@octokit/types"
const octokit = new Octokit(); const octokit = new Octokit()
type GitHubRelease = GetResponseDataTypeFromEndpointMethod<typeof octokit.repos.getLatestRelease>; type GitHubRelease = GetResponseDataTypeFromEndpointMethod<typeof octokit.repos.getLatestRelease>
export interface AppRelease { export interface AppRelease {
stable: GitHubRelease; stable: GitHubRelease
preview: GitHubRelease; preview: GitHubRelease
} }
declare const data: AppRelease; declare const data: AppRelease
export { data }; export { data }
export default defineLoader({ export default defineLoader({
async load(): Promise<AppRelease> { async load(): Promise<AppRelease> {
const { data: stable } = await octokit.repos.getLatestRelease({ const { data: stable } = await octokit.repos.getLatestRelease({
owner: "tachiyomiorg", owner: "tachiyomiorg",
repo: "tachiyomi", repo: "tachiyomi",
}); })
const { data: preview } = await octokit.repos.getLatestRelease({ const { data: preview } = await octokit.repos.getLatestRelease({
owner: "tachiyomiorg", owner: "tachiyomiorg",
repo: "tachiyomi-preview", repo: "tachiyomi-preview",
}); })
return { stable, preview }; return { stable, preview }
}, },
}); })

View File

@ -1,26 +1,26 @@
// https://vitepress.dev/guide/custom-theme // https://vitepress.dev/guide/custom-theme
import DefaultTheme from "vitepress/theme"; import DefaultTheme from "vitepress/theme"
// Import Stylus files // Import Stylus files
import "./styles/base.styl"; import "./styles/base.styl"
// Import Global plugins // Import Global plugins
import "element-plus/theme-chalk/dark/css-vars.css"; import "element-plus/theme-chalk/dark/css-vars.css"
import { VueQueryPlugin } from "@tanstack/vue-query"; import { VueQueryPlugin } from "@tanstack/vue-query"
import { enhanceAppWithTabs } from "vitepress-plugin-tabs/client"; import { enhanceAppWithTabs } from "vitepress-plugin-tabs/client"
// Import Icon components // Import Icon components
import { IconDownload, IconNewspaperVariant, IconBugReport } from "@iconify-prerendered/vue-mdi"; import { IconBugReport, IconDownload, IconNewspaperVariant } from "@iconify-prerendered/vue-mdi"
export default { export default {
extends: DefaultTheme, extends: DefaultTheme,
enhanceApp({ app }) { enhanceApp({ app }) {
app.use(VueQueryPlugin); app.use(VueQueryPlugin)
enhanceAppWithTabs(app); enhanceAppWithTabs(app)
app.component("IconDownload", IconDownload); app.component("IconDownload", IconDownload)
app.component("IconNewspaperVariant", IconNewspaperVariant); app.component("IconNewspaperVariant", IconNewspaperVariant)
app.component("IconBugReport", IconBugReport); app.component("IconBugReport", IconBugReport)
}, },
}; }

View File

@ -1,29 +1,30 @@
import { UseQueryOptions, useQuery } from "@tanstack/vue-query"; import type { UseQueryOptions } from "@tanstack/vue-query"
import axios from "axios"; import { useQuery } from "@tanstack/vue-query"
import { GITHUB_EXTENSION_JSON } from "../../config/constants"; import axios from "axios"
import { GITHUB_EXTENSION_JSON } from "../../config/constants"
export type ReleaseType = "stable" | "preview"; export type ReleaseType = "stable" | "preview"
export interface Extension { export interface Extension {
name: string; name: string
pkg: string; pkg: string
apk: string; apk: string
lang: string; lang: string
code: number; code: number
version: string; version: string
nsfw: number; nsfw: number
hasReadme: number; hasReadme: number
hasChangelog: number; hasChangelog: number
sources: Source[]; sources: Source[]
} }
export interface Source { export interface Source {
name: string; name: string
lang: string; lang: string
id: string; id: string
baseUrl: string; baseUrl: string
versionId: number; versionId: number
hasCloudflare: string; hasCloudflare: string
} }
type UseExtensionsRepositoryQueryOptions<S = Extension[]> = type UseExtensionsRepositoryQueryOptions<S = Extension[]> =
@ -33,12 +34,12 @@ export default function useExtensionsRepositoryQuery<S = Extension[]>(options: U
return useQuery<Extension[], Error, S>({ return useQuery<Extension[], Error, S>({
queryKey: ["extensions"], queryKey: ["extensions"],
queryFn: async () => { queryFn: async () => {
const { data } = await axios.get<Extension[]>(GITHUB_EXTENSION_JSON); const { data } = await axios.get<Extension[]>(GITHUB_EXTENSION_JSON)
return data; return data
}, },
initialData: () => [], initialData: () => [],
refetchOnWindowFocus: false, refetchOnWindowFocus: false,
...options, ...options,
}); })
} }