diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..4c2f52b3 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +auto-install-peers=true +strict-peer-dependencies=false diff --git a/.whitesource b/.whitesource deleted file mode 100644 index 9c7ae90b..00000000 --- a/.whitesource +++ /dev/null @@ -1,14 +0,0 @@ -{ - "scanSettings": { - "baseBranches": [] - }, - "checkRunSettings": { - "vulnerableCheckRunConclusionLevel": "failure", - "displayMode": "diff", - "useMendCheckNames": true - }, - "issueSettings": { - "minSeverityLevel": "LOW", - "issueType": "DEPENDENCY" - } -} \ No newline at end of file diff --git a/package.json b/package.json index 58b48f15..4c7cd898 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git.shin.animevsub", - "version": "0.0.127", + "version": "0.0.137", "description": "Watch Anime without advertising, free, private.", "productName": "AnimeVsub", "author": "Tachibana Shin <45375496+tachibana-shin@users.noreply.github.com>", @@ -20,14 +20,13 @@ "release": "bumpp package.json --commit --tag --push" }, "dependencies": { - "@firebase/analytics": "^0.9.1", - "@firebase/app": "^0.9.1", - "@firebase/firestore": "^3.8.1", + "@firebase/analytics": "^0.9.5", + "@firebase/app": "^0.9.8", + "@firebase/firestore": "^3.10.1", "@fontsource/caveat": "^4.5.10", "@iconify/vue": "^4.1.1", "@quasar/extras": "^1.15.10", "@vueuse/core": "^9.12.0", - "@vueuse/firebase": "^9.12.0", "@vueuse/head": "^1.0.23", "@vueuse/shared": "^9.12.0", "cheerio": "1.0.0-rc.12", @@ -84,6 +83,7 @@ "@types/uuid": "^9.0.0", "@typescript-eslint/eslint-plugin": "^5.49.0", "@typescript-eslint/parser": "^5.49.0", + "@vitest/web-worker": "^0.30.1", "autoprefixer": "^10.4.13", "bumpp": "^8.2.1", "chalk": "^5.2.0", @@ -101,7 +101,7 @@ "vite-plugin-remove-console": "^1.3.0", "vite-plugin-rewrite-all": "^1.0.1", "vite-plugin-windicss": "^1.8.10", - "vitest": "~0.28.3", + "vitest": "~0.30.1", "vue-tsc": "^1.0.24", "windicss": "^3.5.6" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5111f0da..bb6a3ae2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2,14 +2,14 @@ lockfileVersion: '6.0' dependencies: '@firebase/analytics': - specifier: ^0.9.1 - version: 0.9.1(@firebase/app@0.9.1) + specifier: ^0.9.5 + version: 0.9.5(@firebase/app@0.9.8) '@firebase/app': - specifier: ^0.9.1 - version: 0.9.1 + specifier: ^0.9.8 + version: 0.9.8 '@firebase/firestore': - specifier: ^3.8.1 - version: 3.8.1(@firebase/app@0.9.1) + specifier: ^3.10.1 + version: 3.10.1(@firebase/app@0.9.8) '@fontsource/caveat': specifier: ^4.5.10 version: 4.5.10 @@ -22,9 +22,6 @@ dependencies: '@vueuse/core': specifier: ^9.12.0 version: 9.12.0(vue@3.2.45) - '@vueuse/firebase': - specifier: ^9.12.0 - version: 9.12.0(firebase@9.20.0)(vue@3.2.45) '@vueuse/head': specifier: ^1.0.23 version: 1.0.23(vue@3.2.45) @@ -189,6 +186,9 @@ devDependencies: '@typescript-eslint/parser': specifier: ^5.49.0 version: 5.49.0(eslint@8.33.0)(typescript@4.9.4) + '@vitest/web-worker': + specifier: ^0.30.1 + version: 0.30.1(vitest@0.30.1) autoprefixer: specifier: ^10.4.13 version: 10.4.13(postcss@8.4.21) @@ -241,8 +241,8 @@ devDependencies: specifier: ^1.8.10 version: 1.8.10(vite@4.0.4) vitest: - specifier: ~0.28.3 - version: 0.28.3(jsdom@21.1.0)(sass@1.32.11) + specifier: ~0.30.1 + version: 0.30.1(jsdom@21.1.0)(sass@1.32.11) vue-tsc: specifier: ^1.0.24 version: 1.0.24(typescript@4.9.4) @@ -540,38 +540,6 @@ packages: - supports-color dev: true - /@firebase/analytics-compat@0.2.5(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8): - resolution: {integrity: sha512-ohKUrwSoXvyUJdSLuDr82mOqrzgWKyHMUt9/TfYKkyDXnFjNlBcFBpkpl/UHMAOJe0M60YYXiVCZoGQYldCslA==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/analytics': 0.9.5(@firebase/app@0.9.8) - '@firebase/analytics-types': 0.8.0 - '@firebase/app-compat': 0.2.8 - '@firebase/component': 0.6.4 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - dev: false - - /@firebase/analytics-types@0.8.0: - resolution: {integrity: sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==} - dev: false - - /@firebase/analytics@0.9.1(@firebase/app@0.9.1): - resolution: {integrity: sha512-ARXtNHDrjDhVrs5MqmFDpr5yyCw89r1eHLd+Dw9fotAufxL1WTmo6O9bJqKb7QulIJaA84vsFokA3NaO2DNCnQ==} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.1 - '@firebase/component': 0.6.1 - '@firebase/installations': 0.6.1(@firebase/app@0.9.1) - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.0 - tslib: 2.5.0 - dev: false - /@firebase/analytics@0.9.5(@firebase/app@0.9.8): resolution: {integrity: sha512-hJTVs2jLxPXE7hs7D/jaEsgGivrm7tSEl65kb5NkDBWV7QQBUnRfVML/xra9nTFLLJhAdbExZPHg6HfIuMSYEQ==} peerDependencies: @@ -585,66 +553,6 @@ packages: tslib: 2.5.0 dev: false - /@firebase/app-check-compat@0.3.5(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8): - resolution: {integrity: sha512-ji+LxuM2AyFCaJCBfJllnQ1OIedMq+iMwzABlfP9yVrhcR6ZSdCLLhDGMyoENyoPiZo6av+5b3acYUTYrffFeQ==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/app-check': 0.6.5(@firebase/app@0.9.8) - '@firebase/app-check-types': 0.5.0 - '@firebase/app-compat': 0.2.8 - '@firebase/component': 0.6.4 - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - dev: false - - /@firebase/app-check-interop-types@0.2.0: - resolution: {integrity: sha512-+3PQIeX6/eiVK+x/yg8r6xTNR97fN7MahFDm+jiQmDjcyvSefoGuTTNQuuMScGyx3vYUBeZn+Cp9kC0yY/9uxQ==} - dev: false - - /@firebase/app-check-types@0.5.0: - resolution: {integrity: sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==} - dev: false - - /@firebase/app-check@0.6.5(@firebase/app@0.9.8): - resolution: {integrity: sha512-TCHJ+kghqDiNWCXAsPnHaE98CxBfEW9D16CIC3gYVaXrh3w42UNWqbR+S+ggSc7xN+vP9QRhCOY5pvr7rBEEUg==} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.8 - '@firebase/component': 0.6.4 - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - dev: false - - /@firebase/app-compat@0.2.8: - resolution: {integrity: sha512-aG9juNXD+m8gWs6VnrLUWWV1LtJu8W0+uyX5u+Sz6YjDO69JN2jEaxCsb7Wr1egXKKJN1YrhoS+0kQqWakp61Q==} - dependencies: - '@firebase/app': 0.9.8 - '@firebase/component': 0.6.4 - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - dev: false - - /@firebase/app-types@0.9.0: - resolution: {integrity: sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==} - dev: false - - /@firebase/app@0.9.1: - resolution: {integrity: sha512-Z8wOSol+pvp4CFyY1mW+aqdZlrwhW/ha2YXQ6/avJ56c5Hnvt4k6GktZE6o5NyzvfJTgNHryhMtnEJMIuLaT4w==} - dependencies: - '@firebase/component': 0.6.1 - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.0 - idb: 7.0.1 - tslib: 2.5.0 - dev: false - /@firebase/app@0.9.8: resolution: {integrity: sha512-mYoH/aT4Dx6szBBnO7qcEr5ieJRnWU9TENgPiZI5DtkrIDTpW9540KMn996176PkR4GbLKto6rtvUX5P7ii+KQ==} dependencies: @@ -655,60 +563,6 @@ packages: tslib: 2.5.0 dev: false - /@firebase/auth-compat@0.4.0(@firebase/app-compat@0.2.8)(@firebase/app-types@0.9.0)(@firebase/app@0.9.8): - resolution: {integrity: sha512-MS4S90rOjv9/DkumQkKbQs84YgRVHLFQKI+UI3PRdbPO+50Bl3MNXtTyGlLKSIdMjMISeX8IbyBmCdOOTQZmLw==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/app-compat': 0.2.8 - '@firebase/auth': 0.23.0(@firebase/app@0.9.8) - '@firebase/auth-types': 0.12.0(@firebase/app-types@0.9.0)(@firebase/util@1.9.3) - '@firebase/component': 0.6.4 - '@firebase/util': 1.9.3 - node-fetch: 2.6.7 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - - '@firebase/app-types' - - encoding - dev: false - - /@firebase/auth-interop-types@0.2.1: - resolution: {integrity: sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==} - dev: false - - /@firebase/auth-types@0.12.0(@firebase/app-types@0.9.0)(@firebase/util@1.9.3): - resolution: {integrity: sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==} - peerDependencies: - '@firebase/app-types': 0.x - '@firebase/util': 1.x - dependencies: - '@firebase/app-types': 0.9.0 - '@firebase/util': 1.9.3 - dev: false - - /@firebase/auth@0.23.0(@firebase/app@0.9.8): - resolution: {integrity: sha512-OzDs1osO8R/9BIgKLoJCRoDdR4sM/MUVu2mNhMya2qJVH00I1fYqrmGeV3jUH5vcy0MYkJvxa2J7oXetaoKcCg==} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.8 - '@firebase/component': 0.6.4 - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.3 - node-fetch: 2.6.7 - tslib: 2.5.0 - transitivePeerDependencies: - - encoding - dev: false - - /@firebase/component@0.6.1: - resolution: {integrity: sha512-yvKthG0InjFx9aOPnh6gk0lVNfNVEtyq3LwXgZr+hOwD0x/CtXq33XCpqv0sQj5CA4FdMy8OO+y9edI+ZUw8LA==} - dependencies: - '@firebase/util': 1.9.0 - tslib: 2.5.0 - dev: false - /@firebase/component@0.6.4: resolution: {integrity: sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==} dependencies: @@ -716,62 +570,6 @@ packages: tslib: 2.5.0 dev: false - /@firebase/database-compat@0.3.4: - resolution: {integrity: sha512-kuAW+l+sLMUKBThnvxvUZ+Q1ZrF/vFJ58iUY9kAcbX48U03nVzIF6Tmkf0p3WVQwMqiXguSgtOPIB6ZCeF+5Gg==} - dependencies: - '@firebase/component': 0.6.4 - '@firebase/database': 0.14.4 - '@firebase/database-types': 0.10.4 - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - dev: false - - /@firebase/database-types@0.10.4: - resolution: {integrity: sha512-dPySn0vJ/89ZeBac70T+2tWWPiJXWbmRygYv0smT5TfE3hDrQ09eKMF3Y+vMlTdrMWq7mUdYW5REWPSGH4kAZQ==} - dependencies: - '@firebase/app-types': 0.9.0 - '@firebase/util': 1.9.3 - dev: false - - /@firebase/database@0.14.4: - resolution: {integrity: sha512-+Ea/IKGwh42jwdjCyzTmeZeLM3oy1h0mFPsTy6OqCWzcu/KFqRAr5Tt1HRCOBlNOdbh84JPZC47WLU18n2VbxQ==} - dependencies: - '@firebase/auth-interop-types': 0.2.1 - '@firebase/component': 0.6.4 - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.3 - faye-websocket: 0.11.4 - tslib: 2.5.0 - dev: false - - /@firebase/firestore-compat@0.3.7(@firebase/app-compat@0.2.8)(@firebase/app-types@0.9.0)(@firebase/app@0.9.8): - resolution: {integrity: sha512-pwSEh75e0WIQjU6UdZJcdP0AO1Tj2P7r1aIWcBf7kdqTOwZmplxhJ/rXNL6IaKo2fP+/9osXaLZiBH6WWrSbfQ==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/app-compat': 0.2.8 - '@firebase/component': 0.6.4 - '@firebase/firestore': 3.10.1(@firebase/app@0.9.8) - '@firebase/firestore-types': 2.5.1(@firebase/app-types@0.9.0)(@firebase/util@1.9.3) - '@firebase/util': 1.9.3 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - - '@firebase/app-types' - - encoding - dev: false - - /@firebase/firestore-types@2.5.1(@firebase/app-types@0.9.0)(@firebase/util@1.9.3): - resolution: {integrity: sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw==} - peerDependencies: - '@firebase/app-types': 0.x - '@firebase/util': 1.x - dependencies: - '@firebase/app-types': 0.9.0 - '@firebase/util': 1.9.3 - dev: false - /@firebase/firestore@3.10.1(@firebase/app@0.9.8): resolution: {integrity: sha512-p+WQMLkuHECVjB6zoyZYF4OjudquW9IlHsBx7eIfyvOZyOtTEmbSmNrJaWsqCZ/9kDo94XYJx/eZQ2Y4WBAV4A==} engines: {node: '>=10.10.0'} @@ -791,98 +589,6 @@ packages: - encoding dev: false - /@firebase/firestore@3.8.1(@firebase/app@0.9.1): - resolution: {integrity: sha512-oc2HMkUnq/zF+g9o974tp5RVCdXCnrU8e5S98ajfWG/hGV+8pr4i6vIa4z0yEXKWGi4X0FguxrC69z1dxEJbNg==} - engines: {node: '>=10.10.0'} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.1 - '@firebase/component': 0.6.1 - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.0 - '@firebase/webchannel-wrapper': 0.9.0 - '@grpc/grpc-js': 1.7.3 - '@grpc/proto-loader': 0.6.13 - node-fetch: 2.6.7 - tslib: 2.5.0 - transitivePeerDependencies: - - encoding - dev: false - - /@firebase/functions-compat@0.3.4(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8): - resolution: {integrity: sha512-kxVxTGyLV1MBR3sp3mI+eQ6JBqz0G5bk310F8eX4HzDFk4xjk5xY0KdHktMH+edM2xs1BOg0vwvvsAHczIjB+w==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/app-compat': 0.2.8 - '@firebase/component': 0.6.4 - '@firebase/functions': 0.9.4(@firebase/app@0.9.8) - '@firebase/functions-types': 0.6.0 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - - encoding - dev: false - - /@firebase/functions-types@0.6.0: - resolution: {integrity: sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw==} - dev: false - - /@firebase/functions@0.9.4(@firebase/app@0.9.8): - resolution: {integrity: sha512-3H2qh6U+q+nepO5Hds+Ddl6J0pS+zisuBLqqQMRBHv9XpWfu0PnDHklNmE8rZ+ccTEXvBj6zjkPfdxt6NisvlQ==} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.8 - '@firebase/app-check-interop-types': 0.2.0 - '@firebase/auth-interop-types': 0.2.1 - '@firebase/component': 0.6.4 - '@firebase/messaging-interop-types': 0.2.0 - '@firebase/util': 1.9.3 - node-fetch: 2.6.7 - tslib: 2.5.0 - transitivePeerDependencies: - - encoding - dev: false - - /@firebase/installations-compat@0.2.4(@firebase/app-compat@0.2.8)(@firebase/app-types@0.9.0)(@firebase/app@0.9.8): - resolution: {integrity: sha512-LI9dYjp0aT9Njkn9U4JRrDqQ6KXeAmFbRC0E7jI7+hxl5YmRWysq5qgQl22hcWpTk+cm3es66d/apoDU/A9n6Q==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/app-compat': 0.2.8 - '@firebase/component': 0.6.4 - '@firebase/installations': 0.6.4(@firebase/app@0.9.8) - '@firebase/installations-types': 0.5.0(@firebase/app-types@0.9.0) - '@firebase/util': 1.9.3 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - - '@firebase/app-types' - dev: false - - /@firebase/installations-types@0.5.0(@firebase/app-types@0.9.0): - resolution: {integrity: sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==} - peerDependencies: - '@firebase/app-types': 0.x - dependencies: - '@firebase/app-types': 0.9.0 - dev: false - - /@firebase/installations@0.6.1(@firebase/app@0.9.1): - resolution: {integrity: sha512-gpobP09LLLakBfNCL04fyblfyb3oX1pn+iNmELygrcAkXTO13IAMuOzThI+Xk4NHQZMX1p5GFSAiGbG4yfsSUQ==} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.1 - '@firebase/component': 0.6.1 - '@firebase/util': 1.9.0 - idb: 7.0.1 - tslib: 2.5.0 - dev: false - /@firebase/installations@0.6.4(@firebase/app@0.9.8): resolution: {integrity: sha512-u5y88rtsp7NYkCHC3ElbFBrPtieUybZluXyzl7+4BsIz4sqb4vSAuwHEUgCgCeaQhvsnxDEU6icly8U9zsJigA==} peerDependencies: @@ -901,151 +607,6 @@ packages: tslib: 2.5.0 dev: false - /@firebase/messaging-compat@0.2.4(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8): - resolution: {integrity: sha512-lyFjeUhIsPRYDPNIkYX1LcZMpoVbBWXX4rPl7c/rqc7G+EUea7IEtSt4MxTvh6fDfPuzLn7+FZADfscC+tNMfg==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/app-compat': 0.2.8 - '@firebase/component': 0.6.4 - '@firebase/messaging': 0.12.4(@firebase/app@0.9.8) - '@firebase/util': 1.9.3 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - dev: false - - /@firebase/messaging-interop-types@0.2.0: - resolution: {integrity: sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==} - dev: false - - /@firebase/messaging@0.12.4(@firebase/app@0.9.8): - resolution: {integrity: sha512-6JLZct6zUaex4g7HI3QbzeUrg9xcnmDAPTWpkoMpd/GoSVWH98zDoWXMGrcvHeCAIsLpFMe4MPoZkJbrPhaASw==} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.8 - '@firebase/component': 0.6.4 - '@firebase/installations': 0.6.4(@firebase/app@0.9.8) - '@firebase/messaging-interop-types': 0.2.0 - '@firebase/util': 1.9.3 - idb: 7.0.1 - tslib: 2.5.0 - dev: false - - /@firebase/performance-compat@0.2.4(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8): - resolution: {integrity: sha512-nnHUb8uP9G8islzcld/k6Bg5RhX62VpbAb/Anj7IXs/hp32Eb2LqFPZK4sy3pKkBUO5wcrlRWQa6wKOxqlUqsg==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/app-compat': 0.2.8 - '@firebase/component': 0.6.4 - '@firebase/logger': 0.4.0 - '@firebase/performance': 0.6.4(@firebase/app@0.9.8) - '@firebase/performance-types': 0.2.0 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - dev: false - - /@firebase/performance-types@0.2.0: - resolution: {integrity: sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA==} - dev: false - - /@firebase/performance@0.6.4(@firebase/app@0.9.8): - resolution: {integrity: sha512-HfTn/bd8mfy/61vEqaBelNiNnvAbUtME2S25A67Nb34zVuCSCRIX4SseXY6zBnOFj3oLisaEqhVcJmVPAej67g==} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.8 - '@firebase/component': 0.6.4 - '@firebase/installations': 0.6.4(@firebase/app@0.9.8) - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - dev: false - - /@firebase/remote-config-compat@0.2.4(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8): - resolution: {integrity: sha512-FKiki53jZirrDFkBHglB3C07j5wBpitAaj8kLME6g8Mx+aq7u9P7qfmuSRytiOItADhWUj7O1JIv7n9q87SuwA==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/app-compat': 0.2.8 - '@firebase/component': 0.6.4 - '@firebase/logger': 0.4.0 - '@firebase/remote-config': 0.4.4(@firebase/app@0.9.8) - '@firebase/remote-config-types': 0.3.0 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - dev: false - - /@firebase/remote-config-types@0.3.0: - resolution: {integrity: sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA==} - dev: false - - /@firebase/remote-config@0.4.4(@firebase/app@0.9.8): - resolution: {integrity: sha512-x1ioTHGX8ZwDSTOVp8PBLv2/wfwKzb4pxi0gFezS5GCJwbLlloUH4YYZHHS83IPxnua8b6l0IXUaWd0RgbWwzQ==} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.8 - '@firebase/component': 0.6.4 - '@firebase/installations': 0.6.4(@firebase/app@0.9.8) - '@firebase/logger': 0.4.0 - '@firebase/util': 1.9.3 - tslib: 2.5.0 - dev: false - - /@firebase/storage-compat@0.3.2(@firebase/app-compat@0.2.8)(@firebase/app-types@0.9.0)(@firebase/app@0.9.8): - resolution: {integrity: sha512-wvsXlLa9DVOMQJckbDNhXKKxRNNewyUhhbXev3t8kSgoCotd1v3MmqhKKz93ePhDnhHnDs7bYHy+Qa8dRY6BXw==} - peerDependencies: - '@firebase/app-compat': 0.x - dependencies: - '@firebase/app-compat': 0.2.8 - '@firebase/component': 0.6.4 - '@firebase/storage': 0.11.2(@firebase/app@0.9.8) - '@firebase/storage-types': 0.8.0(@firebase/app-types@0.9.0)(@firebase/util@1.9.3) - '@firebase/util': 1.9.3 - tslib: 2.5.0 - transitivePeerDependencies: - - '@firebase/app' - - '@firebase/app-types' - - encoding - dev: false - - /@firebase/storage-types@0.8.0(@firebase/app-types@0.9.0)(@firebase/util@1.9.3): - resolution: {integrity: sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==} - peerDependencies: - '@firebase/app-types': 0.x - '@firebase/util': 1.x - dependencies: - '@firebase/app-types': 0.9.0 - '@firebase/util': 1.9.3 - dev: false - - /@firebase/storage@0.11.2(@firebase/app@0.9.8): - resolution: {integrity: sha512-CtvoFaBI4hGXlXbaCHf8humajkbXhs39Nbh6MbNxtwJiCqxPy9iH3D3CCfXAvP0QvAAwmJUTK3+z9a++Kc4nkA==} - peerDependencies: - '@firebase/app': 0.x - dependencies: - '@firebase/app': 0.9.8 - '@firebase/component': 0.6.4 - '@firebase/util': 1.9.3 - node-fetch: 2.6.7 - tslib: 2.5.0 - transitivePeerDependencies: - - encoding - dev: false - - /@firebase/util@1.9.0: - resolution: {integrity: sha512-oeoq/6Sr9btbwUQs5HPfeww97bf7qgBbkknbDTXpRaph2LZ23O9XLCE5tJy856SBmGQfO4xBZP8dyryLLM2nSQ==} - dependencies: - tslib: 2.5.0 - dev: false - /@firebase/util@1.9.3: resolution: {integrity: sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==} dependencies: @@ -1065,7 +626,7 @@ packages: engines: {node: ^8.13.0 || >=10.10.0} dependencies: '@grpc/proto-loader': 0.7.4 - '@types/node': 18.11.18 + '@types/node': 18.8.0 dev: false /@grpc/proto-loader@0.6.13: @@ -1948,7 +1509,7 @@ packages: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 18.11.18 + '@types/node': 18.8.0 dev: true /@types/chai-subset@1.3.3: @@ -1977,7 +1538,7 @@ packages: /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.8.0 dev: true /@types/cordova@0.0.34: @@ -1987,7 +1548,7 @@ packages: /@types/express-serve-static-core@4.17.33: resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.8.0 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 dev: true @@ -2015,7 +1576,7 @@ packages: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 18.11.18 + '@types/node': 18.8.0 dev: true /@types/group-array@1.0.1: @@ -2051,7 +1612,7 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.8.0 dev: true /@types/long@4.0.2: @@ -2076,10 +1637,10 @@ packages: /@types/node@18.11.18: resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} + dev: true /@types/node@18.8.0: resolution: {integrity: sha512-u+h43R6U8xXDt2vzUaVP3VwjjLyOJk6uEciZS8OSyziUQGOwmk+l+4drxcsDboHXwyTaqS1INebghmWMRxq3LA==} - dev: true /@types/offscreencanvas@2019.7.0: resolution: {integrity: sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==} @@ -2109,7 +1670,7 @@ packages: /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.8.0 dev: true /@types/semver@7.3.13: @@ -2120,7 +1681,7 @@ packages: resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==} dependencies: '@types/mime': 3.0.1 - '@types/node': 18.11.18 + '@types/node': 18.8.0 dev: true /@types/set-cookie-parser@2.4.2: @@ -2320,38 +1881,56 @@ packages: vue: 3.2.45 dev: true - /@vitest/expect@0.28.3: - resolution: {integrity: sha512-dnxllhfln88DOvpAK1fuI7/xHwRgTgR4wdxHldPaoTaBu6Rh9zK5b//v/cjTkhOfNP/AJ8evbNO8H7c3biwd1g==} + /@vitest/expect@0.30.1: + resolution: {integrity: sha512-c3kbEtN8XXJSeN81iDGq29bUzSjQhjES2WR3aColsS4lPGbivwLtas4DNUe0jD9gg/FYGIteqOenfU95EFituw==} dependencies: - '@vitest/spy': 0.28.3 - '@vitest/utils': 0.28.3 + '@vitest/spy': 0.30.1 + '@vitest/utils': 0.30.1 chai: 4.3.7 dev: true - /@vitest/runner@0.28.3: - resolution: {integrity: sha512-P0qYbATaemy1midOLkw7qf8jraJszCoEvjQOSlseiXZyEDaZTZ50J+lolz2hWiWv6RwDu1iNseL9XLsG0Jm2KQ==} + /@vitest/runner@0.30.1: + resolution: {integrity: sha512-W62kT/8i0TF1UBCNMRtRMOBWJKRnNyv9RrjIgdUryEe0wNpGZvvwPDLuzYdxvgSckzjp54DSpv1xUbv4BQ0qVA==} dependencies: - '@vitest/utils': 0.28.3 + '@vitest/utils': 0.30.1 + concordance: 5.0.4 p-limit: 4.0.0 pathe: 1.1.0 dev: true - /@vitest/spy@0.28.3: - resolution: {integrity: sha512-jULA6suS6CCr9VZfr7/9x97pZ0hC55prnUNHNrg5/q16ARBY38RsjsfhuUXt6QOwvIN3BhSS0QqPzyh5Di8g6w==} + /@vitest/snapshot@0.30.1: + resolution: {integrity: sha512-fJZqKrE99zo27uoZA/azgWyWbFvM1rw2APS05yB0JaLwUIg9aUtvvnBf4q7JWhEcAHmSwbrxKFgyBUga6tq9Tw==} + dependencies: + magic-string: 0.30.0 + pathe: 1.1.0 + pretty-format: 27.5.1 + dev: true + + /@vitest/spy@0.30.1: + resolution: {integrity: sha512-YfJeIf37GvTZe04ZKxzJfnNNuNSmTEGnla2OdL60C8od16f3zOfv9q9K0nNii0NfjDJRt/CVN/POuY5/zTS+BA==} dependencies: - tinyspy: 1.0.2 + tinyspy: 2.1.0 dev: true - /@vitest/utils@0.28.3: - resolution: {integrity: sha512-YHiQEHQqXyIbhDqETOJUKx9/psybF7SFFVCNfOvap0FvyUqbzTSDCa3S5lL4C0CLXkwVZttz9xknDoyHMguFRQ==} + /@vitest/utils@0.30.1: + resolution: {integrity: sha512-/c8Xv2zUVc+rnNt84QF0Y0zkfxnaGhp87K2dYJMLtLOIckPzuxLVzAtFCicGFdB4NeBHNzTRr1tNn7rCtQcWFA==} dependencies: - cli-truncate: 3.1.0 - diff: 5.1.0 + concordance: 5.0.4 loupe: 2.3.6 - picocolors: 1.0.0 pretty-format: 27.5.1 dev: true + /@vitest/web-worker@0.30.1(vitest@0.30.1): + resolution: {integrity: sha512-fHe81VYe/Ch6VrM83UUB874ZZ2qzbDAee1MrGwPd3KN6btGfBdeCSu8AO+lvxVxUVQFw7dNrMRnIRkYYtf3YUg==} + peerDependencies: + vitest: '*' + dependencies: + debug: 4.3.4 + vitest: 0.30.1(jsdom@21.1.0)(sass@1.32.11) + transitivePeerDependencies: + - supports-color + dev: true + /@volar/language-core@1.0.24: resolution: {integrity: sha512-vTN+alJiWwK0Pax6POqrmevbtFW2dXhjwWiW/MW4f48eDYPLdyURWcr8TixO7EN/nHsUBj2udT7igFKPtjyAKg==} dependencies: @@ -2479,19 +2058,6 @@ packages: - vue dev: false - /@vueuse/firebase@9.12.0(firebase@9.20.0)(vue@3.2.45): - resolution: {integrity: sha512-dN1bp91cogGXWWsJxM5MUvhHBstUB/j5fM/D6ocVH1UxMfHwWU/zYjbvVBygPWUBvD9JB9svzuE0wS1S7LIfZA==} - peerDependencies: - firebase: '>=9.0.0' - dependencies: - '@vueuse/shared': 9.12.0(vue@3.2.45) - firebase: 9.20.0 - vue-demi: 0.13.11(vue@3.2.45) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: false - /@vueuse/head@1.0.23(vue@3.2.45): resolution: {integrity: sha512-CiC9VWYbvwAqjWDBJH4WfQfBk7NWMZpvmpvIUYsm3X+aa8QHMiDGzR+RFKZSUtykiCGnSZk97yIvo5eJBmSh8A==} peerDependencies: @@ -2895,6 +2461,10 @@ packages: readable-stream: 3.6.0 dev: true + /blueimp-md5@2.19.0: + resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} + dev: true + /bmp-js@0.1.0: resolution: {integrity: sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==} dev: true @@ -3260,14 +2830,6 @@ packages: engines: {node: '>=6'} dev: true - /cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - slice-ansi: 5.0.0 - string-width: 5.1.2 - dev: true - /cli-width@3.0.0: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} @@ -3400,6 +2962,20 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true + /concordance@5.0.4: + resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} + engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} + dependencies: + date-time: 3.1.0 + esutils: 2.0.3 + fast-diff: 1.2.0 + js-string-escape: 1.0.1 + lodash: 4.17.21 + md5-hex: 3.0.1 + semver: 7.3.8 + well-known-symbols: 2.0.0 + dev: true + /config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} dependencies: @@ -3607,6 +3183,13 @@ packages: whatwg-url: 11.0.0 dev: true + /date-time@3.1.0: + resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} + engines: {node: '>=6'} + dependencies: + time-zone: 1.0.0 + dev: true + /dayjs@1.11.7: resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} dev: false @@ -3810,11 +3393,6 @@ packages: engines: {node: '>=8'} dev: true - /diff@5.1.0: - resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} - engines: {node: '>=0.3.1'} - dev: true - /dijkstrajs@1.0.2: resolution: {integrity: sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==} dev: false @@ -5040,6 +4618,10 @@ packages: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true + /fast-diff@1.2.0: + resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} + dev: true + /fast-glob@3.2.12: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} @@ -5065,13 +4647,6 @@ packages: reusify: 1.0.4 dev: true - /faye-websocket@0.11.4: - resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} - engines: {node: '>=0.8.0'} - dependencies: - websocket-driver: 0.7.4 - dev: false - /fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} dependencies: @@ -5192,39 +4767,6 @@ packages: semver-regex: 2.0.0 dev: true - /firebase@9.20.0: - resolution: {integrity: sha512-qkSfdotdgZuMNCi4ddMLT+Pr18m021SkzImgplpihZOSx0utWdO39TgHivMfurlgp0fp4eQ2U4YEDPfP+Iq4bw==} - dependencies: - '@firebase/analytics': 0.9.5(@firebase/app@0.9.8) - '@firebase/analytics-compat': 0.2.5(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8) - '@firebase/app': 0.9.8 - '@firebase/app-check': 0.6.5(@firebase/app@0.9.8) - '@firebase/app-check-compat': 0.3.5(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8) - '@firebase/app-compat': 0.2.8 - '@firebase/app-types': 0.9.0 - '@firebase/auth': 0.23.0(@firebase/app@0.9.8) - '@firebase/auth-compat': 0.4.0(@firebase/app-compat@0.2.8)(@firebase/app-types@0.9.0)(@firebase/app@0.9.8) - '@firebase/database': 0.14.4 - '@firebase/database-compat': 0.3.4 - '@firebase/firestore': 3.10.1(@firebase/app@0.9.8) - '@firebase/firestore-compat': 0.3.7(@firebase/app-compat@0.2.8)(@firebase/app-types@0.9.0)(@firebase/app@0.9.8) - '@firebase/functions': 0.9.4(@firebase/app@0.9.8) - '@firebase/functions-compat': 0.3.4(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8) - '@firebase/installations': 0.6.4(@firebase/app@0.9.8) - '@firebase/installations-compat': 0.2.4(@firebase/app-compat@0.2.8)(@firebase/app-types@0.9.0)(@firebase/app@0.9.8) - '@firebase/messaging': 0.12.4(@firebase/app@0.9.8) - '@firebase/messaging-compat': 0.2.4(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8) - '@firebase/performance': 0.6.4(@firebase/app@0.9.8) - '@firebase/performance-compat': 0.2.4(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8) - '@firebase/remote-config': 0.4.4(@firebase/app@0.9.8) - '@firebase/remote-config-compat': 0.2.4(@firebase/app-compat@0.2.8)(@firebase/app@0.9.8) - '@firebase/storage': 0.11.2(@firebase/app@0.9.8) - '@firebase/storage-compat': 0.3.2(@firebase/app-compat@0.2.8)(@firebase/app-types@0.9.0)(@firebase/app@0.9.8) - '@firebase/util': 1.9.3 - transitivePeerDependencies: - - encoding - dev: false - /flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -5746,10 +5288,6 @@ packages: toidentifier: 1.0.1 dev: true - /http-parser-js@0.5.8: - resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} - dev: false - /http-proxy-agent@5.0.0: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} @@ -6047,11 +5585,6 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - /is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - dev: true - /is-function@1.0.2: resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} dev: true @@ -6304,6 +5837,11 @@ packages: resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==} dev: true + /js-string-escape@1.0.1: + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} + engines: {node: '>= 0.8'} + dev: true + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -6632,6 +6170,13 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true + /magic-string@0.30.0: + resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + /make-dir@1.3.0: resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} engines: {node: '>=4'} @@ -6646,6 +6191,13 @@ packages: semver: 6.3.0 dev: true + /md5-hex@3.0.1: + resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} + engines: {node: '>=8'} + dependencies: + blueimp-md5: 2.19.0 + dev: true + /mdn-data@2.0.14: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} dev: true @@ -6762,13 +6314,13 @@ packages: minimist: 1.2.7 dev: true - /mlly@1.1.0: - resolution: {integrity: sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==} + /mlly@1.2.0: + resolution: {integrity: sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==} dependencies: acorn: 8.8.2 pathe: 1.1.0 - pkg-types: 1.0.1 - ufo: 1.0.1 + pkg-types: 1.0.2 + ufo: 1.1.1 dev: true /ms@2.0.0: @@ -7365,11 +6917,11 @@ packages: pngjs: 3.4.0 dev: true - /pkg-types@1.0.1: - resolution: {integrity: sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==} + /pkg-types@1.0.2: + resolution: {integrity: sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==} dependencies: jsonc-parser: 3.2.0 - mlly: 1.1.0 + mlly: 1.2.0 pathe: 1.1.0 dev: true @@ -7516,7 +7068,7 @@ packages: '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 '@types/long': 4.0.2 - '@types/node': 18.11.18 + '@types/node': 18.8.0 long: 4.0.0 dev: false @@ -7535,7 +7087,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 18.11.18 + '@types/node': 18.8.0 long: 5.2.1 dev: false @@ -7908,6 +7460,7 @@ packages: /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} @@ -8177,14 +7730,6 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true - /slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - dev: true - /sort-array@4.1.5: resolution: {integrity: sha512-Ya4peoS1fgFN42RN1REk2FgdNOeLIEMKFGJvs7VTP3OklF8+kl2SkpVliZ4tk/PurWsrWRsdNdU+tgyOBkB9sA==} engines: {node: '>=10'} @@ -8261,8 +7806,8 @@ packages: engines: {node: '>= 0.8'} dev: true - /std-env@3.3.1: - resolution: {integrity: sha512-3H20QlwQsSm2OvAxWIYhs+j01MzzqwMwGiiO1NQaJYZgJZFPuAbf95/DiKRBSTYIJ2FeGUc+B/6mPGcWP9dO3Q==} + /std-env@3.3.2: + resolution: {integrity: sha512-uUZI65yrV2Qva5gqE0+A7uVAvO40iPo6jGhs7s8keRfHCmtg+uB2X6EiLGCI9IgL1J17xGhvoOqSz79lzICPTA==} dev: true /strict-uri-encode@1.1.0: @@ -8364,8 +7909,8 @@ packages: engines: {node: '>=8'} dev: true - /strip-literal@1.0.0: - resolution: {integrity: sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==} + /strip-literal@1.0.1: + resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} dependencies: acorn: 8.8.2 dev: true @@ -8481,6 +8026,11 @@ packages: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true + /time-zone@1.0.0: + resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} + engines: {node: '>=4'} + dev: true + /timed-out@4.0.1: resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} engines: {node: '>=0.10.0'} @@ -8490,21 +8040,21 @@ packages: resolution: {integrity: sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==} dev: true - /tinybench@2.3.1: - resolution: {integrity: sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==} + /tinybench@2.4.0: + resolution: {integrity: sha512-iyziEiyFxX4kyxSp+MtY1oCH/lvjH3PxFN8PGCDeqcZWAJ/i+9y+nL85w99PxVzrIvew/GSkSbDYtiGVa85Afg==} dev: true /tinycolor2@1.5.2: resolution: {integrity: sha512-h80m9GPFGbcLzZByXlNSEhp1gf8Dy+VX/2JCGUZsWLo7lV1mnE/XlxGYgRBoMLJh1lIDXP0EMC4RPTjlRaV+Bg==} dev: true - /tinypool@0.3.1: - resolution: {integrity: sha512-zLA1ZXlstbU2rlpA4CIeVaqvWq41MTWqLY3FfsAXgC8+f7Pk7zroaJQxDgxn1xNudKW6Kmj4808rPFShUlIRmQ==} + /tinypool@0.4.0: + resolution: {integrity: sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==} engines: {node: '>=14.0.0'} dev: true - /tinyspy@1.0.2: - resolution: {integrity: sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==} + /tinyspy@2.1.0: + resolution: {integrity: sha512-7eORpyqImoOvkQJCSkL0d0mB4NHHIFAy4b1u8PHdDa7SjGS2njzl6/lyGoZLm+eyYEtlUmFGE0rFj66SWxZgQQ==} engines: {node: '>=14.0.0'} dev: true @@ -8696,8 +8246,8 @@ packages: resolution: {integrity: sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==} dev: false - /ufo@1.0.1: - resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==} + /ufo@1.1.1: + resolution: {integrity: sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==} dev: true /uglify-js@3.17.4: @@ -8882,19 +8432,17 @@ packages: engines: {node: '>= 0.8'} dev: true - /vite-node@0.28.3(@types/node@18.11.18)(sass@1.32.11): - resolution: {integrity: sha512-uJJAOkgVwdfCX8PUQhqLyDOpkBS5+j+FdbsXoPVPDlvVjRkb/W/mLYQPSL6J+t8R0UV8tJSe8c9VyxVQNsDSyg==} - engines: {node: '>=v14.16.0'} + /vite-node@0.30.1(@types/node@18.8.0)(sass@1.32.11): + resolution: {integrity: sha512-vTikpU/J7e6LU/8iM3dzBo8ZhEiKZEKRznEMm+mJh95XhWaPrJQraT/QsT2NWmuEf+zgAoMe64PKT7hfZ1Njmg==} + engines: {node: '>=v14.18.0'} hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4 - mlly: 1.1.0 + mlly: 1.2.0 pathe: 1.1.0 picocolors: 1.0.0 - source-map: 0.6.1 - source-map-support: 0.5.21 - vite: 4.0.4(@types/node@18.11.18)(sass@1.32.11) + vite: 4.0.4(@types/node@18.8.0)(sass@1.32.11) transitivePeerDependencies: - '@types/node' - less @@ -8958,41 +8506,6 @@ packages: fsevents: 2.3.2 dev: true - /vite@4.0.4(@types/node@18.11.18)(sass@1.32.11): - resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - '@types/node': 18.11.18 - esbuild: 0.16.17 - postcss: 8.4.21 - resolve: 1.22.1 - rollup: 3.12.0 - sass: 1.32.11 - optionalDependencies: - fsevents: 2.3.2 - dev: true - /vite@4.0.4(@types/node@18.8.0)(sass@1.32.11): resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -9028,9 +8541,9 @@ packages: fsevents: 2.3.2 dev: true - /vitest@0.28.3(jsdom@21.1.0)(sass@1.32.11): - resolution: {integrity: sha512-N41VPNf3VGJlWQizGvl1P5MGyv3ZZA2Zvh+2V8L6tYBAAuqqDK4zExunT1Cdb6dGfZ4gr+IMrnG8d4Z6j9ctPw==} - engines: {node: '>=v14.16.0'} + /vitest@0.30.1(jsdom@21.1.0)(sass@1.32.11): + resolution: {integrity: sha512-y35WTrSTlTxfMLttgQk4rHcaDkbHQwDP++SNwPb+7H8yb13Q3cu2EixrtHzF27iZ8v0XCciSsLg00RkPAzB/aA==} + engines: {node: '>=v14.18.0'} hasBin: true peerDependencies: '@edge-runtime/vm': '*' @@ -9038,6 +8551,9 @@ packages: '@vitest/ui': '*' happy-dom: '*' jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -9049,31 +8565,39 @@ packages: optional: true jsdom: optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true dependencies: '@types/chai': 4.3.4 '@types/chai-subset': 1.3.3 - '@types/node': 18.11.18 - '@vitest/expect': 0.28.3 - '@vitest/runner': 0.28.3 - '@vitest/spy': 0.28.3 - '@vitest/utils': 0.28.3 + '@types/node': 18.8.0 + '@vitest/expect': 0.30.1 + '@vitest/runner': 0.30.1 + '@vitest/snapshot': 0.30.1 + '@vitest/spy': 0.30.1 + '@vitest/utils': 0.30.1 acorn: 8.8.2 acorn-walk: 8.2.0 cac: 6.7.14 chai: 4.3.7 + concordance: 5.0.4 debug: 4.3.4 jsdom: 21.1.0 local-pkg: 0.4.3 + magic-string: 0.30.0 pathe: 1.1.0 picocolors: 1.0.0 source-map: 0.6.1 - std-env: 3.3.1 - strip-literal: 1.0.0 - tinybench: 2.3.1 - tinypool: 0.3.1 - tinyspy: 1.0.2 - vite: 4.0.4(@types/node@18.11.18)(sass@1.32.11) - vite-node: 0.28.3(@types/node@18.11.18)(sass@1.32.11) + std-env: 3.3.2 + strip-literal: 1.0.1 + tinybench: 2.4.0 + tinypool: 0.4.0 + vite: 4.0.4(@types/node@18.8.0)(sass@1.32.11) + vite-node: 0.30.1(@types/node@18.8.0)(sass@1.32.11) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -9225,19 +8749,10 @@ packages: wildcard: 2.0.0 dev: true - /websocket-driver@0.7.4: - resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} - engines: {node: '>=0.8.0'} - dependencies: - http-parser-js: 0.5.8 - safe-buffer: 5.2.1 - websocket-extensions: 0.1.4 - dev: false - - /websocket-extensions@0.1.4: - resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} - engines: {node: '>=0.8.0'} - dev: false + /well-known-symbols@2.0.0: + resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} + engines: {node: '>=6'} + dev: true /whatwg-encoding@2.0.0: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} diff --git a/src/apis/parser/ajax/player-fb.spec.ts b/src/apis/parser/ajax/player-fb.spec.ts new file mode 100644 index 00000000..685707f8 --- /dev/null +++ b/src/apis/parser/ajax/player-fb.spec.ts @@ -0,0 +1,15 @@ +import AjaxPlayerFBParser from "./player-fb" + +describe("player", () => { + test("AjaxPlayerFBParser", () => { + expect( + AjaxPlayerFBParser( + '

Chọn Server:

DUFBHDX(ADS)' + ) + ).toEqual({ + id: "2", + play: "api", + hash: "SEAiZc7pSjNkB2hc9Z9HAgcH_OmZzuBHytI_Q51KqtyHg-T0WfhwQAmVV6i4TM4VtHrk09wA6YFztU0wUl4fCw", + }) + }) +}) diff --git a/src/apis/parser/ajax/player-fb.ts b/src/apis/parser/ajax/player-fb.ts new file mode 100644 index 00000000..0ace754d --- /dev/null +++ b/src/apis/parser/ajax/player-fb.ts @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { parserDom } from "../__helpers__/parserDom" + +export default function AjaxPlayerFBParser(html: string) { + const $ = parserDom(html) + const a = $("a:eq(1)") + + return { + id: a.attr("data-id")!, + play: a.attr("data-play")!, + hash: a.attr("data-href")!, + } +} diff --git a/src/apis/parser/phim/[id]/[chap].ts b/src/apis/parser/phim/[id]/[chap].ts index 33acab5e..22e1e66a 100644 --- a/src/apis/parser/phim/[id]/[chap].ts +++ b/src/apis/parser/phim/[id]/[chap].ts @@ -18,7 +18,7 @@ export default function PhimIdChap(html: string) { hash: $item.attr("data-hash")!, name: $item.text().trim(), - } + } as const }) .toArray() const [day, hour, minus] = @@ -32,7 +32,7 @@ export default function PhimIdChap(html: string) { const poster = $(".TPostBg img").attr("src")! return { - chaps, + chaps: chaps as Readonly, update: !day ? null : ([dayTextToNum(day.toLowerCase()), +hour, +minus] as [ diff --git a/src/apis/runs/ajax/player-fb.ts b/src/apis/runs/ajax/player-fb.ts new file mode 100644 index 00000000..966dc5c4 --- /dev/null +++ b/src/apis/runs/ajax/player-fb.ts @@ -0,0 +1,23 @@ +import type AjaxPlayerFBParser from "src/apis/parser/ajax/player-fb" +import Worker from "src/apis/workers/ajax/player-fb?worker" +import { PostWorker } from "src/apis/wrap-worker" +import { post } from "src/logic/http" + +import { PlayerLink } from "./player-link" + +export async function PlayerFB(episodeId: string) { + const { data: json } = await post("/ajax/player?v=2019a", { + episodeId, + backup: 1, + }) + + const data = JSON.parse(json) + + // eslint-disable-next-line functional/no-throw-statement + if (!data.success) throw new Error("Failed load player facebook") + + const config = await PostWorker(Worker, data.html) + + + return await PlayerLink(config) +} diff --git a/src/apis/runs/ajax/player-link.ts b/src/apis/runs/ajax/player-link.ts new file mode 100644 index 00000000..adc5efa1 --- /dev/null +++ b/src/apis/runs/ajax/player-link.ts @@ -0,0 +1,72 @@ +import { getQualityByLabel } from "src/logic/get-quality-by-label" +import { post } from "src/logic/http" + +const addProtocolUrl = (file: string) => + file.startsWith("http") ? file : `https:${file}` + +interface PlayerLinkReturn { + readonly link: { + readonly file: string + readonly label: "FHD|HD" | "HD" | "FHD" | `${720 | 360 | 340}p` + readonly qualityCode: ReturnType + readonly preload?: string + readonly type: + | "hls" + | "aac" + | "f4a" + | "mp4" + | "f4v" + | "m3u" + | "m3u8" + | "m4v" + | "mov" + | "mp3" + | "mpeg" + | "oga" + | "ogg" + | "ogv" + | "vorbis" + | "webm" + | "youtube" + }[] + readonly playTech: "api" | "trailer" +} +export function PlayerLink(config: { + id: string + play: string + hash: string +}): Promise { + const { id, play, hash: link } = config + return post("/ajax/player?v=2019a", { + id, + play, + link, + backuplinks: "1", + }).then(({ data }) => { + // eslint-disable-next-line functional/no-throw-statement + if (!data) throw new Error("unknown_error") + type Writeable = { + -readonly [P in keyof T]: T[P] extends object ? Writeable : T[P] + } + const config = JSON.parse(data) as Writeable + config.link.forEach((item) => { + item.file = addProtocolUrl(item.file) + switch ( + (item.label as typeof item.label | undefined)?.toUpperCase() as + | Uppercase> + | undefined + ) { + case "HD": + if (item.preload) item.label = "FHD|HD" + break + case undefined: + item.label = "HD" + break + } + item.qualityCode = getQualityByLabel(item.label) + item.type ??= "mp4" + }) + + return config + }) +} diff --git a/src/apis/workers/ajax/player-fb.ts b/src/apis/workers/ajax/player-fb.ts new file mode 100644 index 00000000..1587d944 --- /dev/null +++ b/src/apis/workers/ajax/player-fb.ts @@ -0,0 +1,4 @@ +import PlayerFB from "src/apis/parser/ajax/player-fb" +import { WrapWorker } from "src/apis/wrap-worker" + +WrapWorker(PlayerFB) diff --git a/src/components/BrtPlayer.vue b/src/components/BrtPlayer.vue index 7d5e6956..007bb18d 100644 --- a/src/components/BrtPlayer.vue +++ b/src/components/BrtPlayer.vue @@ -581,7 +581,79 @@ class="mr-6 desktop-mode:mr-5 text-weight-normal art-btn" > + {{ settingsStore.player.server }} + + +
+ {{ t('may-chu-phat') }} + + +
+
+ +
    +
  • + {{ label }} +
  • +
+
+
+
+ + + {{ t('may-chu-phat') }} + + + +
  • - {{ html }} + {{ label }}
@@ -739,7 +810,7 @@ anchor="top middle" self="bottom middle" :offset="[-25, 20]" - class="rounded-xl shadow-xl min-w-[200px]" + class="rounded-xl shadow-xl min-w-[200px] flex column flex-nowrap overflow-visible" :class="{ 'm-transparency': settingsStore.ui.menuTransparency, }" @@ -759,9 +830,28 @@ />
+ {{ t('may-chu-phat') }} +
+
+ {{ label }} +
+ +
{{ t("chat-luong") }}
@@ -769,16 +859,15 @@ dense flat no-caps - class="px-2 flex-1 text-weight-norrmal py-2 c--main rounded-xl" - v-for="({ html }, index) in sources" + class="px-2 flex-1 text-weight-norrmal py-2 rounded-xl" + v-for="({ label, qualityCode }) in sources" :class="{ 'c--main': - html === artQuality || - (!artQuality && index === 0), + qualityCode === artQuality, }" - :key="html" - @click="setArtQuality(html)" - >{{ html }}{{ qualityCode }}
@@ -790,7 +879,7 @@ dense flat no-caps - class="px-2 flex-1 text-weight-norrmal py-2 c--main rounded-xl" + class="px-2 flex-1 text-weight-norrmal py-2 rounded-xl" v-for="{ name, value } in playbackRates" :key="name" :class=" @@ -998,14 +1087,14 @@ import { QTabPanels, QTabs, QTooltip, - throttle, useQuasar, } from "quasar" +import type { PlayerLink } from "src/apis/runs/ajax/player-link" import { useMemoControl } from "src/composibles/memo-control" import { - CONFIRMATION_TIME_IS_ACTUALLY_WATCHING, DELAY_SAVE_VIEWING_PROGRESS, playbackRates, + servers, } from "src/constants" import { checkContentEditable } from "src/helpers/checkContentEditable" import { scrollXIntoView, scrollYIntoView } from "src/helpers/scrollIntoView" @@ -1033,8 +1122,6 @@ import { import { useI18n } from "vue-i18n" import { onBeforeRouteLeave, useRouter } from "vue-router" -import type { Source } from "./sources" - const { t } = useI18n() // fix toolip fullscreen not hide if change fullscreen @@ -1060,7 +1147,7 @@ interface SiblingChap { } const props = defineProps<{ - sources?: Source[] + sources?: Awaited>["link"] currentSeason: string nameCurrentSeason?: string currentChap?: string @@ -1181,8 +1268,15 @@ const menuChapsRef = ref() // =========================== huuuu player API。馬鹿馬鹿しい ==================================== const currentStream = computed(() => { - return props.sources?.find((item) => item.html === artQuality.value) + return props.sources?.find((item) => item.qualityCode === artQuality.value) }) +if (import.meta.env.DEV) + watch( + () => props.sources, + (sources) => { + console.log("sources changed: ", sources) + } + ) const video = ref() watch( @@ -1340,8 +1434,18 @@ watch( () => tooltipModeMovieRef.value?.hide() ) -const artQuality = ref() -const setArtQuality = (value: string) => { +const _artQuality = ref>["link"][0]['qualityCode']>() +const artQuality = computed({ + get() { + if (props.sources?.find((item) => item.qualityCode === _artQuality.value)) return _artQuality.value + + return props.sources?.[0]?.qualityCode + }, + set(value) { +_artQuality.value = value + } +}) +const setArtQuality = (value: Exclude) => { artQuality.value = value addNotice(t("chat-luong-da-chuyen-sang-_value", [value])) } @@ -1412,37 +1516,43 @@ const emit = defineEmits<{ ): void }>() -const storeFirstSaving = new Set() -{ - // eslint-disable-next-line functional/no-let, no-undef - let timeout: NodeJS.Timeout | number | null = null +const firstSaveStore = new Set() +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function throttle void>( + fn: T +): T & { + cancel: () => void +} { // eslint-disable-next-line functional/no-let - let uidChapTimeout: string | null = null - onBeforeUnmount(() => { - if (timeout) clearTimeout(timeout) - }) - const watcher = watch(artPlaying, (artPlaying) => { - if (artPlaying) { - if (timeout) { - if (uidChapTimeout === uidChap.value) return - console.log("stop timeout add first saving because change chap") - clearTimeout(timeout) - } - timeout = setTimeout(() => { - console.log("allow first saving") - storeFirstSaving.add(uidChap.value) - }, CONFIRMATION_TIME_IS_ACTUALLY_WATCHING) - uidChapTimeout = uidChap.value - } else { - if (timeout) { - console.log("stop timeout add first saving") - clearTimeout(timeout) - uidChapTimeout = null - watcher() - } + let wait = false + // eslint-disable-next-line functional/no-let, no-undef + let timeout: NodeJS.Timeout | number | undefined + // eslint-disable-next-line functional/functional-parameters, @typescript-eslint/no-explicit-any + const cb = function (...args: any[]) { + if (wait === false) { + wait = true + timeout = setTimeout( + () => { + firstSaveStore.add(uidChap.value) + fn(...args) + wait = false + }, + firstSaveStore.has(uidChap.value) + ? DELAY_SAVE_VIEWING_PROGRESS + : DELAY_SAVE_VIEWING_PROGRESS / 2 + ) } - }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any + + cb.cancel = () => { + clearTimeout(timeout) + wait = false + } + + return cb } + // eslint-disable-next-line functional/no-let let processingSaveCurTimeIn: string | null = null const saveCurTimeToPer = throttle( @@ -1453,48 +1563,45 @@ const saveCurTimeToPer = throttle( dur: number, nameCurrentChap: string ) => { + emit("cur-update", { + cur, + dur, + id: currentChap, + }) + + console.log("call main fn cur time") const uid = uidChap.value // 255 byte + console.log({ uid, processingSaveCurTimeIn }) + if (processingSaveCurTimeIn === uid) return // in progressing save this + processingSaveCurTimeIn = uid if (!(await createSeason())) return if (stateStorageStore.disableAutoRestoration === 2) return - if (processingSaveCurTimeIn === uid) return // in progressing save this - processingSaveCurTimeIn = uid - - await historyStore - .setProgressChap(currentSeason, currentChap, { - cur, - dur, - name: nameCurrentChap, - }) - .catch((err) => console.warn("save viewing progress failed: ", err)) - .finally(() => { - emit("cur-update", { + console.log("%ccall sav curTime", "color: green") + try { + await historyStore + .setProgressChap(currentSeason, currentChap, { cur, dur, - id: currentChap, + name: nameCurrentChap, }) - console.log("save viewing progress") + .catch((err) => console.warn("save viewing progress failed: ", err)) + } catch {} - processingSaveCurTimeIn = null - }) - }, - DELAY_SAVE_VIEWING_PROGRESS + console.log("save viewing progress") + + processingSaveCurTimeIn = null + } ) -const throttleEmitCurUpdate = throttle(() => { - if (props.currentChap) - emit("cur-update", { - cur: artCurrentTime.value, - dur: artDuration.value, - id: props.currentChap, - }) -}, DELAY_SAVE_VIEWING_PROGRESS) +watch(uidChap, saveCurTimeToPer.cancel) function onVideoTimeUpdate() { if ( artPlaying.value && !currentingTime.value && artControlShow.value && !showMenuQuality.value && + !showMenuServer.value && !showMenuPlaybackRate.value && !showMenuSettings.value && !showMenuSelectChap.value && @@ -1505,14 +1612,11 @@ function onVideoTimeUpdate() { artControlShow.value = false } - if (!progressRestored) return + if (progressRestored !== uidChap.value) return if (!props.currentChap) return if (typeof props.nameCurrentChap !== "string") return - if (!storeFirstSaving.has(uidChap.value)) { - throttleEmitCurUpdate() - return console.log("bypass because not first saving") - } + console.log("call throw emit") saveCurTimeToPer( props.currentSeason, props.currentChap, @@ -1655,8 +1759,26 @@ function runRemount() { // eslint-disable-next-line functional/no-let let currentHls: Hls onBeforeUnmount(() => currentHls?.destroy()) -function remount(resetCurrentTime?: boolean) { - currentHls?.destroy() +function remount(resetCurrentTime?: boolean, noDestroy = false) { + if (!noDestroy) currentHls?.destroy() + else { + const type = currentStream.value?.type + + if ( + (type === "hls" || type === "m3u" || type === "m3u8") && + Hls.isSupported() + ) { + // current stream is HLS -> no cancel if canPlay + } else { + console.warn("can't play HLS stream") + // cancel + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + video.value!.oncanplay = function () { + currentHls?.destroy() + this.oncanplay = null + } + } + } if (!currentStream.value) { $q.notify({ @@ -1666,201 +1788,200 @@ function remount(resetCurrentTime?: boolean) { return } - const { url, type } = currentStream.value + const { file, type } = currentStream.value const currentTime = artCurrentTime.value const playing = artPlaying.value || artEnded artEnded = false - switch (type) { - case "hls": - case "m3u": - // eslint-disable-next-line no-case-declarations - const hls = new Hls({ - debug: import.meta.env.isDev, - progressive: true, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - pLoader: class CustomLoader extends (Hls.DefaultConfig.loader as any) { - loadInternal(): void { - const { config, context } = this - if (!config) { - return - } - - const { stats } = this - stats.loading.first = 0 - stats.loaded = 0 - - const controller = new AbortController() - const xhr = (this.loader = { - readyState: 0, - status: 0, - abort() { - controller.abort() - }, - onreadystatechange: <(() => void) | null>null, - onprogress: < - ((eventt: { loaded: number; total: number }) => void) | null - >null, - response: null, - responseText: null, - }) - const headers = new Headers() - if (this.context.headers) - for (const [key, val] of Object.entries(this.context.headers)) - headers.set(key, val as string) - - if (context.rangeEnd) { - headers.set( - "Range", - "bytes=" + context.rangeStart + "-" + (context.rangeEnd - 1) - ) - } + if ( + (type === "hls" || type === "m3u" || type === "m3u8") && + Hls.isSupported() + ) { + const hls = new Hls({ + debug: import.meta.env.isDev, + progressive: true, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + pLoader: class CustomLoader extends (Hls.DefaultConfig.loader as any) { + loadInternal(): void { + const { config, context } = this + if (!config) { + return + } - xhr.onreadystatechange = this.readystatechange.bind(this) - xhr.onprogress = this.loadprogress.bind(this) - self.clearTimeout(this.requestTimeout) - this.requestTimeout = self.setTimeout( - this.loadtimeout.bind(this), - config.timeout + const { stats } = this + stats.loading.first = 0 + stats.loaded = 0 + + const controller = new AbortController() + const xhr = (this.loader = { + readyState: 0, + status: 0, + abort() { + controller.abort() + }, + onreadystatechange: <(() => void) | null>null, + onprogress: < + ((eventt: { loaded: number; total: number }) => void) | null + >null, + response: null, + responseText: null, + }) + const headers = new Headers() + if (this.context.headers) + for (const [key, val] of Object.entries(this.context.headers)) + headers.set(key, val as string) + + if (context.rangeEnd) { + headers.set( + "Range", + "bytes=" + context.rangeStart + "-" + (context.rangeEnd - 1) ) + } - fetchJava(context.url + "#animevsub-vsub", { - headers, - signal: controller.signal, - }) - .then(async (res) => { - // eslint-disable-next-line functional/no-let - let byteLength: number - if (context.responseType === "arraybuffer") { - xhr.response = await res.arrayBuffer() - byteLength = xhr.response.byteLength - } else { - xhr.responseText = await res.text() - byteLength = xhr.responseText.length - } - - xhr.readyState = 4 - xhr.status = 200 - - xhr.onprogress?.({ - loaded: byteLength, - total: byteLength, - }) - // eslint-disable-next-line promise/always-return - xhr.onreadystatechange?.() - }) - .catch((e) => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.callbacks!.onError( - { code: xhr.status, text: e.message }, - context, - xhr - ) + xhr.onreadystatechange = this.readystatechange.bind(this) + xhr.onprogress = this.loadprogress.bind(this) + self.clearTimeout(this.requestTimeout) + this.requestTimeout = self.setTimeout( + this.loadtimeout.bind(this), + config.timeout + ) + + fetchJava(context.url + "#animevsub-vsub", { + headers, + signal: controller.signal, + }) + .then(async (res) => { + // eslint-disable-next-line functional/no-let + let byteLength: number + if (context.responseType === "arraybuffer") { + xhr.response = await res.arrayBuffer() + byteLength = xhr.response.byteLength + } else { + xhr.responseText = await res.text() + byteLength = xhr.responseText.length + } + + xhr.readyState = 4 + xhr.status = 200 + + xhr.onprogress?.({ + loaded: byteLength, + total: byteLength, }) - } - } as unknown as PlaylistLoaderConstructor, - }) - currentHls = hls - // customLoader(hls.config) - hls.loadSource(url) + // eslint-disable-next-line promise/always-return + xhr.onreadystatechange?.() + }) + .catch((e) => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + this.callbacks!.onError( + { code: xhr.status, text: e.message }, + context, + xhr + ) + }) + } + } as unknown as PlaylistLoaderConstructor, + }) + currentHls = hls + // customLoader(hls.config) + hls.loadSource(file) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + hls.attachMedia(video.value!) + hls.on(Hls.Events.MANIFEST_PARSED, () => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - hls.attachMedia(video.value!) - hls.on(Hls.Events.MANIFEST_PARSED, () => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (playing) video.value!.play() - }) - // eslint-disable-next-line no-case-declarations, functional/no-let - let needSwapCodec = false - // eslint-disable-next-line no-case-declarations, functional/no-let, no-undef - let timeoutUnneedSwapCodec: NodeJS.Timeout | number | null = null - hls.on(Hls.Events.ERROR, (event, data) => { - if (data.fatal) { - console.warn("Player fatal: ", data) - switch (data.type) { - case Hls.ErrorTypes.NETWORK_ERROR: { - // try to recover network error - $q.notify({ - message: t("loi-mang-khong-kha-dung"), - position: "bottom-right", - timeout: 0, - actions: [ - { - label: t("thu-lai"), - color: "yellow", - noCaps: true, - handler: () => hls.startLoad(), - }, - { - icon: "close", - round: true, - }, - ], - }) - break + if (playing) video.value!.play() + }) + // eslint-disable-next-line functional/no-let + let needSwapCodec = false + // eslint-disable-next-line functional/no-let, no-undef + let timeoutUnneedSwapCodec: NodeJS.Timeout | number | null = null + hls.on(Hls.Events.ERROR, (event, data) => { + if (data.fatal) { + console.warn("Player fatal: ", data) + switch (data.type) { + case Hls.ErrorTypes.NETWORK_ERROR: { + // try to recover network error + $q.notify({ + message: t("loi-mang-khong-kha-dung"), + position: "bottom-right", + timeout: 0, + actions: [ + { + label: t("thu-lai"), + color: "yellow", + noCaps: true, + handler: () => hls.startLoad(), + }, + { + icon: "close", + round: true, + }, + ], + }) + break + } + case Hls.ErrorTypes.MEDIA_ERROR: { + const playing = artPlaying.value + if (timeoutUnneedSwapCodec) { + clearTimeout(timeoutUnneedSwapCodec) + timeoutUnneedSwapCodec = null } - case Hls.ErrorTypes.MEDIA_ERROR: { - const playing = artPlaying.value + console.warn("fatal media error encountered, try to recover") + if (needSwapCodec) { + hls.swapAudioCodec() + needSwapCodec = false if (timeoutUnneedSwapCodec) { clearTimeout(timeoutUnneedSwapCodec) timeoutUnneedSwapCodec = null } - console.warn("fatal media error encountered, try to recover") - if (needSwapCodec) { - hls.swapAudioCodec() + } else { + needSwapCodec = true + timeoutUnneedSwapCodec = setTimeout(() => { needSwapCodec = false - if (timeoutUnneedSwapCodec) { - clearTimeout(timeoutUnneedSwapCodec) - timeoutUnneedSwapCodec = null - } - } else { - needSwapCodec = true - timeoutUnneedSwapCodec = setTimeout(() => { - needSwapCodec = false - timeoutUnneedSwapCodec = null - }, 1_000) - } - hls.recoverMediaError() - if (playing) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - video.value!.play() - break + timeoutUnneedSwapCodec = null + }, 1_000) } - default: { - $q.notify({ - message: t("da-gap-su-co-khi-phat-lai"), - position: "bottom-right", - timeout: 0, - actions: [ - { - label: t("thu-lai"), - color: "white", - handler() { - console.log("retry force") - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - video.value!.load() - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - video.value!.play() - }, - }, - { - label: t("remount"), - color: "white", - handler: remount, + hls.recoverMediaError() + if (playing) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + video.value!.play() + break + } + default: { + $q.notify({ + message: t("da-gap-su-co-khi-phat-lai"), + position: "bottom-right", + timeout: 0, + actions: [ + { + label: t("thu-lai"), + color: "white", + handler() { + console.log("retry force") + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + video.value!.load() + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + video.value!.play() }, - ], - }) - break - } + }, + { + label: t("remount"), + color: "white", + handler: remount, + }, + ], + }) + break } - } else { - console.warn("Player error: ", data) } - }) - break - default: - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - video.value!.src = url + } else { + console.warn("Player error: ", data) + } + }) + } else { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + video.value!.src = file } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -1882,40 +2003,36 @@ const watcherVideoTagReady = watch(video, (video) => { // eslint-disable-next-line promise/catch-or-return Promise.resolve().then(watcherVideoTagReady) // fix this not ready value + // pre set volume to default + setArtVolume(artVolume.value) + + // eslint-disable-next-line functional/no-let + let currentEpStream: null | string = null watch( - () => currentStream.value?.url, + () => currentStream.value?.file, (url) => { if (!url) return currentHls?.destroy() console.log("set url art %s", url) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if ((Hls as unknown as any).isSupported()) { - remount(true) - } else { - const canPlay = video.canPlayType("application/vnd.apple.mpegurl") - if (canPlay === "probably" || canPlay === "maybe") { - video.src = url - } - } + // // eslint-disable-next-line @typescript-eslint/no-explicit-any + // if ((Hls as unknown as any).isSupported()) { + remount( + currentEpStream !== uidChap.value, + currentEpStream === uidChap.value + ) + currentEpStream = uidChap.value + // } else { + // const canPlay = video.canPlayType("application/vnd.apple.mpegurl") + // if (canPlay === "probably" || canPlay === "maybe") { + // video.src = url + // } + // } }, { immediate: true } ) }) -// re-set quality if quality not in sources -watch( - () => props.sources, - (sources) => { - if (!sources || sources.length === 0) return - // not ready quality on this - if (!artQuality.value || !currentStream.value) { - artQuality.value = sources[0].html // not use setArtQuality because skip notify - } - }, - { immediate: true } -) - const currentingTime = ref(false) const progressInnerRef = ref() @@ -2173,6 +2290,7 @@ watch(showDialogChapter, (status) => { }) const showMenuQuality = ref(false) +const showMenuServer = ref(false) const showMenuPlaybackRate = ref(false) const showMenuSettings = ref(false) const showMenuSelectChap = ref(false) diff --git a/src/components/sources.ts b/src/components/sources.ts deleted file mode 100644 index cf823341..00000000 --- a/src/components/sources.ts +++ /dev/null @@ -1,21 +0,0 @@ -export interface Source { - html: string - url: string - type: - | "hls" - | "aac" - | "f4a" - | "mp4" - | "f4v" - | "m3u" - | "m4v" - | "mov" - | "mp3" - | "mpeg" - | "oga" - | "ogg" - | "ogv" - | "vorbis" - | "webm" - | "youtube" -} diff --git a/src/constants.ts b/src/constants.ts index 2709d954..e6c84211 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -2,6 +2,10 @@ export const labelToQuality: Record = { HD: "720p", SD: "480p", } +export const servers = { + DU: "High", + FB: "Low", +} as const export const playbackRates = [ { name: "0.5x", @@ -30,8 +34,6 @@ export const playbackRates = [ ] export const DELAY_SAVE_VIEWING_PROGRESS = 20_000 // x4 6s -export const CONFIRMATION_TIME_IS_ACTUALLY_WATCHING = - DELAY_SAVE_VIEWING_PROGRESS / 4 export const TIMEOUT_GET_LAST_EP_VIEWING_IN_STORE = 5_000 // 5s diff --git a/src/global.d.ts b/src/global.d.ts index 8b54b48e..3614dfc0 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -12,7 +12,7 @@ interface PostOptions { interface HttpResponse { headers: Record - data: ResponseType extends "arraybuffer" ? ArrayBuffer : string + data: string url: string status: number } diff --git a/src/i18n/messages/en-US.json b/src/i18n/messages/en-US.json index e61f4511..77ec6b32 100644 --- a/src/i18n/messages/en-US.json +++ b/src/i18n/messages/en-US.json @@ -245,5 +245,6 @@ "xoa-danh-sach-phat": "delete playlist", "xoa-khoi-danh-sach-phat": "Remove from playlist", "yeu-cau-dang-nhap-lai": "Requires re-login", - "yeu-thich": "Favourite" + "yeu-thich": "Favourite", + "may-chu-phat": "Broadcast server" } diff --git a/src/i18n/messages/ja-JP.json b/src/i18n/messages/ja-JP.json index a9efe259..cadf60f4 100644 --- a/src/i18n/messages/ja-JP.json +++ b/src/i18n/messages/ja-JP.json @@ -245,5 +245,6 @@ "xoa-danh-sach-phat": "プレイリストを削除", "xoa-khoi-danh-sach-phat": "プレイリストから削除", "yeu-cau-dang-nhap-lai": "再ログインが必要", - "yeu-thich": "お気に入り" + "yeu-thich": "お気に入り", + "may-chu-phat": "ブロードキャスト サーバー" } diff --git a/src/i18n/messages/vi-VN.json b/src/i18n/messages/vi-VN.json index 1d9b06e2..a35269c7 100644 --- a/src/i18n/messages/vi-VN.json +++ b/src/i18n/messages/vi-VN.json @@ -245,5 +245,6 @@ "xoa-danh-sach-phat": "Xóa danh sách phát", "xoa-khoi-danh-sach-phat": "Xóa khỏi danh sách phát", "yeu-cau-dang-nhap-lai": "Yêu cầu đăng nhập lại", - "yeu-thich": "Yêu thích" + "yeu-thich": "Yêu thích", + "may-chu-phat": "Máy chủ phát" } diff --git a/src/i18n/messages/zh-CN.json b/src/i18n/messages/zh-CN.json index 59d2b4d3..5c040b71 100644 --- a/src/i18n/messages/zh-CN.json +++ b/src/i18n/messages/zh-CN.json @@ -245,5 +245,6 @@ "xoa-danh-sach-phat": "删除播放列表", "xoa-khoi-danh-sach-phat": "从播放列表中删除", "yeu-cau-dang-nhap-lai": "需要重新登录", - "yeu-thich": "最喜欢的" + "yeu-thich": "最喜欢的", + "may-chu-phat": "广播服务器" } diff --git a/src/logic/get-quality-by-label.spec.ts b/src/logic/get-quality-by-label.spec.ts new file mode 100644 index 00000000..38b0e0f5 --- /dev/null +++ b/src/logic/get-quality-by-label.spec.ts @@ -0,0 +1,13 @@ +import { getQualityByLabel } from "./get-quality-by-label" + +describe("get-quality-by-label", () => { + test("should label is HD", () => { + expect(getQualityByLabel("HD")).toBe("720p") + }) + test("should label is 720p", () => { + expect(getQualityByLabel("720p")).toBe("720p") + }) + test("should label is FHD|HD", () => { + expect(getQualityByLabel("FHD|HD")).toBe("1080p|720p") + }) +}) diff --git a/src/logic/get-quality-by-label.ts b/src/logic/get-quality-by-label.ts new file mode 100644 index 00000000..f812c4f9 --- /dev/null +++ b/src/logic/get-quality-by-label.ts @@ -0,0 +1,17 @@ +import type { PlayerLink } from "src/apis/runs/ajax/player-link" + +const map = { + "FHD|HD": "1080p|720p", + FHD: "1080p", + HD: "720p", + SD: "480p", +} as const +export function getQualityByLabel( + label: Awaited>["link"][0]["label"] +) { + return ( + (map[label as keyof typeof map] as + | (typeof map)[keyof typeof map] + | undefined) ?? (label as Exclude) + ) +} diff --git a/src/logic/unflat.ts b/src/logic/unflat.ts index b777bb73..3ef93759 100644 --- a/src/logic/unflat.ts +++ b/src/logic/unflat.ts @@ -1,4 +1,4 @@ -export function unflat(array: T[], size: number): T[][] { +export function unflat(array: readonly T[], size: number): T[][] { const { length } = array const max = ~~(length / size) diff --git a/src/pages/phim/_season.interface.ts b/src/pages/phim/_season.interface.ts index fa1d3061..23c2f802 100644 --- a/src/pages/phim/_season.interface.ts +++ b/src/pages/phim/_season.interface.ts @@ -26,3 +26,29 @@ export type ProgressWatchStore = Map< status: "queue" } > + +export interface ConfigPlayer { + readonly link: { + readonly file: string + readonly label?: "HD" | "FHD" | `${720 | 360 | 340}p` + readonly preload?: string + readonly type: + | "hls" + | "aac" + | "f4a" + | "mp4" + | "f4v" + | "m3u" + | "m4v" + | "mov" + | "mp3" + | "mpeg" + | "oga" + | "ogg" + | "ogv" + | "vorbis" + | "webm" + | "youtube" + }[] + readonly playTech: "api" | "trailer" +} diff --git a/src/pages/phim/_season.vue b/src/pages/phim/_season.vue index fa19218f..8abe4b9e 100644 --- a/src/pages/phim/_season.vue +++ b/src/pages/phim/_season.vue @@ -42,10 +42,13 @@ }) " /> -
+
@@ -401,7 +404,6 @@