mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-16 04:41:47 +00:00
Compare commits
54 Commits
26fa1f85b2
...
snyk-fix-c
| Author | SHA1 | Date | |
|---|---|---|---|
| fdd55e10bc | |||
| c9ae7cb277 | |||
| e455932754 | |||
| a1e3bf23be | |||
| 8ccd510700 | |||
| c0a495640f | |||
| 6060e138ee | |||
| 98b2e182fb | |||
| 715ddb8923 | |||
| 3104111f6b | |||
| e064c37859 | |||
| 1de223b4ca | |||
| 50a1365a6f | |||
| cc83804491 | |||
| 92cf306439 | |||
| a8be510a07 | |||
| 58524fb3c1 | |||
| aeb6997117 | |||
| 0116188623 | |||
| af63edb058 | |||
| bd0ac52832 | |||
| 5b537d2a9e | |||
| d9a7c352d3 | |||
| 84add37441 | |||
| 9a88f11f16 | |||
| 51b4441e5c | |||
| 29784e6a39 | |||
| e2981c22fa | |||
| d7513dcc20 | |||
| 5c0face2c9 | |||
| a1805f7662 | |||
| 46889098e8 | |||
| 607938c170 | |||
| 58a03db898 | |||
| 67ef3408dc | |||
| 27f16e26b3 | |||
| e38200bc1f | |||
| 736e63d259 | |||
| 721271d902 | |||
| a2151930ec | |||
| bdc9f42681 | |||
| 0b3c6f9e1f | |||
| ebe373bdc6 | |||
| ab91e6d735 | |||
| be3ae4d789 | |||
| 336b7fe5e9 | |||
| 5ecd39f324 | |||
| eb50596961 | |||
| aede0cd643 | |||
| 25f51784c3 | |||
| 7acac6d11c | |||
| 1972ef70b5 | |||
| c4455ed3d2 | |||
| c1a06ab955 |
88
changelog.md
88
changelog.md
@ -2,8 +2,96 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [v3.11.0](https://github.com/th-ch/youtube-music/compare/v3.10.0...v3.11.0)
|
||||
|
||||
- Fixed missing videochange dataupdated event when using shuffle [`#3659`](https://github.com/th-ch/youtube-music/pull/3659)
|
||||
- feat(synced-lyrics): preferred provider (global/per-song) [`#3741`](https://github.com/th-ch/youtube-music/pull/3741)
|
||||
- feat(api-server): send shuffle state over websocket [`#3837`](https://github.com/th-ch/youtube-music/pull/3837)
|
||||
- feat(synced-lyrics): add new "spacer" [`#3742`](https://github.com/th-ch/youtube-music/pull/3742)
|
||||
- feat(downloader): Add context menu button for playlists and albums [`#3768`](https://github.com/th-ch/youtube-music/pull/3768)
|
||||
- feat(transparent-player): new plugin for Acrylic, Mica or Tabbed effects [`#3529`](https://github.com/th-ch/youtube-music/pull/3529)
|
||||
- fix(audio-compressor): real-time behavior and duplicated audio bug [`#3786`](https://github.com/th-ch/youtube-music/pull/3786)
|
||||
- fix: Added Min height and width to the window which doesnt breaks the UI responsiveness [`#3602`](https://github.com/th-ch/youtube-music/pull/3602)
|
||||
- chore(deps): update dependency discord-api-types to v0.38.23 [`#3833`](https://github.com/th-ch/youtube-music/pull/3833)
|
||||
- feat(plugin): Custom output device plugin [`#3789`](https://github.com/th-ch/youtube-music/pull/3789)
|
||||
- chore(deps): update dependency @babel/runtime to v7.28.4 [`#3831`](https://github.com/th-ch/youtube-music/pull/3831)
|
||||
- chore(deps): update eslint monorepo to v9.35.0 [`#3829`](https://github.com/th-ch/youtube-music/pull/3829)
|
||||
- feat(api-server): Add websocket as `/api/v1/ws` route [`#3707`](https://github.com/th-ch/youtube-music/pull/3707)
|
||||
- feat(api-server): Improved api-server volume and like/dislike state [`#3592`](https://github.com/th-ch/youtube-music/pull/3592)
|
||||
- fix(deps): update dependency i18next to v25.5.2 [`#3826`](https://github.com/th-ch/youtube-music/pull/3826)
|
||||
- fix(deps): update dependency virtua to v0.42.2 [`#3827`](https://github.com/th-ch/youtube-music/pull/3827)
|
||||
- fix(exponential-volume): volume desync bug [`#3787`](https://github.com/th-ch/youtube-music/pull/3787)
|
||||
- feat(synced-lyrics): thai romanization [`#3618`](https://github.com/th-ch/youtube-music/pull/3618)
|
||||
- feat(discord): add option to display artist/title in status [`#3692`](https://github.com/th-ch/youtube-music/pull/3692)
|
||||
- chore(deps): update playwright monorepo to v1.55.0 [`#3819`](https://github.com/th-ch/youtube-music/pull/3819)
|
||||
- fix(deps): update dependency i18next to v25.5.1 [`#3820`](https://github.com/th-ch/youtube-music/pull/3820)
|
||||
- fix(deps): update dependency virtua to v0.42.0 [`#3821`](https://github.com/th-ch/youtube-music/pull/3821)
|
||||
- fix(deps): update dependency zod to v4.1.5 [`#3822`](https://github.com/th-ch/youtube-music/pull/3822)
|
||||
- chore(deps): update eslint monorepo to v9.34.0 [`#3818`](https://github.com/th-ch/youtube-music/pull/3818)
|
||||
- chore(deps): update actions/setup-node action to v5 [`#3823`](https://github.com/th-ch/youtube-music/pull/3823)
|
||||
- chore(deps): update dependency electron to v38 [`#3824`](https://github.com/th-ch/youtube-music/pull/3824)
|
||||
- chore(deps): update dependency @stylistic/eslint-plugin to v5.3.1 [`#3817`](https://github.com/th-ch/youtube-music/pull/3817)
|
||||
- fix(deps): update dependency serve to v14.2.5 [`#3816`](https://github.com/th-ch/youtube-music/pull/3816)
|
||||
- feat(discord): add song & artist URLs to rich presence [`#3737`](https://github.com/th-ch/youtube-music/pull/3737)
|
||||
- fix: fix #3621 [`#3774`](https://github.com/th-ch/youtube-music/pull/3774)
|
||||
- feat(refactor): PluginDefinition::platform [`#3665`](https://github.com/th-ch/youtube-music/pull/3665)
|
||||
- chore(docs): update copyright footer year [`#3792`](https://github.com/th-ch/youtube-music/pull/3792)
|
||||
- chore(deps): update dependency vite-plugin-inspect to v11.3.3 [`#3814`](https://github.com/th-ch/youtube-music/pull/3814)
|
||||
- fix(deps): update dependency @floating-ui/dom to v1.7.4 [`#3815`](https://github.com/th-ch/youtube-music/pull/3815)
|
||||
- fix(deps): update dependency @ghostery/adblocker-electron to v2.11.6 [`#3770`](https://github.com/th-ch/youtube-music/pull/3770)
|
||||
- chore(deps): update dependency discord-api-types to v0.38.22 [`#3813`](https://github.com/th-ch/youtube-music/pull/3813)
|
||||
- chore(deps): update dependency @types/semver to v7.7.1 [`#3812`](https://github.com/th-ch/youtube-music/pull/3812)
|
||||
- fix(deps): update dependency @ghostery/adblocker-electron-preload to v2.11.6 [`#3771`](https://github.com/th-ch/youtube-music/pull/3771)
|
||||
- fix(deps): update dependency @hono/node-server to v1.19.1 [`#3759`](https://github.com/th-ch/youtube-music/pull/3759)
|
||||
- chore(deps): update dependency typescript-eslint to v8.42.0 [`#3761`](https://github.com/th-ch/youtube-music/pull/3761)
|
||||
- chore(deps): update dependency node-gyp to v11.4.2 [`#3772`](https://github.com/th-ch/youtube-music/pull/3772)
|
||||
- chore(deps): update actions/checkout action to v5 [`#3757`](https://github.com/th-ch/youtube-music/pull/3757)
|
||||
- chore(deps): update dependency vite to v7.1.5 [`#3760`](https://github.com/th-ch/youtube-music/pull/3760)
|
||||
- fix(deps): update dependency hono to v4.9.6 [security] [`#3807`](https://github.com/th-ch/youtube-music/pull/3807)
|
||||
- chore(deps): update dependency electron to v37.3.1 [security] [`#3806`](https://github.com/th-ch/youtube-music/pull/3806)
|
||||
- chore(deps): bump hono from 4.9.2 to 4.9.6 [`#3805`](https://github.com/th-ch/youtube-music/pull/3805)
|
||||
- chore(deps): update playwright monorepo to v1.54.2 [`#3713`](https://github.com/th-ch/youtube-music/pull/3713)
|
||||
- chore(deps): update dependency vite to v7.1.2 [`#3710`](https://github.com/th-ch/youtube-music/pull/3710)
|
||||
- chore(deps): update dependency @stylistic/eslint-plugin to v5.2.3 [`#3754`](https://github.com/th-ch/youtube-music/pull/3754)
|
||||
- chore(deps): update dependency @babel/runtime to v7.28.3 [`#3753`](https://github.com/th-ch/youtube-music/pull/3753)
|
||||
- chore(deps): update dependency discord-api-types to v0.38.20 [`#3706`](https://github.com/th-ch/youtube-music/pull/3706)
|
||||
- fix(deps): update dependency @floating-ui/dom to v1.7.3 [`#3714`](https://github.com/th-ch/youtube-music/pull/3714)
|
||||
- chore(deps): update dependency vite-plugin-solid to v2.11.8 [`#3711`](https://github.com/th-ch/youtube-music/pull/3711)
|
||||
- chore(deps): update dependency rollup to v4.46.2 [`#3709`](https://github.com/th-ch/youtube-music/pull/3709)
|
||||
- chore(deps): update dependency @electron/universal to v3.0.1 [`#3705`](https://github.com/th-ch/youtube-music/pull/3705)
|
||||
- chore(deps): update dependency electron to v37.3.0 [`#3708`](https://github.com/th-ch/youtube-music/pull/3708)
|
||||
- chore(docs): Grammar mistakes [`#3722`](https://github.com/th-ch/youtube-music/pull/3722)
|
||||
- Fixes the error 500 for /auth/ endpoint [`#3627`](https://github.com/th-ch/youtube-music/pull/3627)
|
||||
- feat: add custom window title option [`#3656`](https://github.com/th-ch/youtube-music/pull/3656)
|
||||
- fix(deps): update dependency zod to v4.0.10 [`#3686`](https://github.com/th-ch/youtube-music/pull/3686)
|
||||
- chore(deps): update dependency @babel/runtime to v7.28.2 [`#3687`](https://github.com/th-ch/youtube-music/pull/3687)
|
||||
- chore(deps): update dependency rollup to v4.46.1 [`#3632`](https://github.com/th-ch/youtube-music/pull/3632)
|
||||
- chore(deps): update dependency electron to v38.0.0-alpha.10 [`#3681`](https://github.com/th-ch/youtube-music/pull/3681)
|
||||
- chore(deps): update dependency eslint-config-prettier to v10.1.8 [`#3676`](https://github.com/th-ch/youtube-music/pull/3676)
|
||||
- chore(deps): update dependency eslint-plugin-prettier to v5.5.3 [`#3678`](https://github.com/th-ch/youtube-music/pull/3678)
|
||||
- fix(deps): update dependency @ghostery/adblocker-electron to v2.11.3 [`#3679`](https://github.com/th-ch/youtube-music/pull/3679)
|
||||
- chore(deps): update dependency discord-api-types to v0.38.17 [`#3620`](https://github.com/th-ch/youtube-music/pull/3620)
|
||||
- chore(deps): update dependency esbuild to v0.25.8 [`#3675`](https://github.com/th-ch/youtube-music/pull/3675)
|
||||
- chore(deps): update dependency @stylistic/eslint-plugin to v5.2.2 [`#3636`](https://github.com/th-ch/youtube-music/pull/3636)
|
||||
- fix(deps): update dependency @hono/node-server to v1.17.1 [`#3625`](https://github.com/th-ch/youtube-music/pull/3625)
|
||||
- fix(deps): update dependency hono to v4.8.7 [`#3567`](https://github.com/th-ch/youtube-music/pull/3567)
|
||||
- chore(deps): update dependency typescript-eslint to v8.38.0 [`#3628`](https://github.com/th-ch/youtube-music/pull/3628)
|
||||
- chore(deps): update dependency electron to v38.0.0-alpha.9 [`#3626`](https://github.com/th-ch/youtube-music/pull/3626)
|
||||
- fix(Skip Disliked Song): updated querySelector [`#3667`](https://github.com/th-ch/youtube-music/pull/3667)
|
||||
- chore(deps): update dependency vite to v7.0.11 [`#3624`](https://github.com/th-ch/youtube-music/pull/3624)
|
||||
- fix(deps): update dependency @hono/zod-validator to v0.7.1 [`#3616`](https://github.com/th-ch/youtube-music/pull/3616)
|
||||
- fix(discord-rpc, scrobbler): Align artist and title with the last.fm's de facto standard [`#3358`](https://github.com/th-ch/youtube-music/issues/3358) [`#3641`](https://github.com/th-ch/youtube-music/issues/3641)
|
||||
- fix: fix #3621 (#3774) [`#3621`](https://github.com/th-ch/youtube-music/issues/3621)
|
||||
- fix: fix #3661 [`#3661`](https://github.com/th-ch/youtube-music/issues/3661)
|
||||
- fix: fix #3613, fix #3651 [`#3613`](https://github.com/th-ch/youtube-music/issues/3613) [`#3651`](https://github.com/th-ch/youtube-music/issues/3651)
|
||||
- chore: remove unused deps [`2a81a4e`](https://github.com/th-ch/youtube-music/commit/2a81a4e887cb5cc3c91a672302db6da3c15544e8)
|
||||
- chore(i18n): Translated using Weblate (Swedish) [`0a6f244`](https://github.com/th-ch/youtube-music/commit/0a6f244035f17724ab1934f3cb2e011adf838e09)
|
||||
- fix: bump dependencies [`5ba65ea`](https://github.com/th-ch/youtube-music/commit/5ba65ea1221236478efa8cb61bca3ffb1bb2d061)
|
||||
|
||||
#### [v3.10.0](https://github.com/th-ch/youtube-music/compare/v3.9.0...v3.10.0)
|
||||
|
||||
> 13 July 2025
|
||||
|
||||
- fix(deps): update dependency butterchurn to v3.0.0-beta.5 [`#3610`](https://github.com/th-ch/youtube-music/pull/3610)
|
||||
- chore(deps): update eslint monorepo to v9.31.0 [`#3600`](https://github.com/th-ch/youtube-music/pull/3600)
|
||||
- chore(deps): update dependency rollup to v4.45.0 [`#3568`](https://github.com/th-ch/youtube-music/pull/3568)
|
||||
|
||||
@ -45,7 +45,7 @@ export default defineConfig({
|
||||
formats: ['es'],
|
||||
},
|
||||
outDir: 'dist/main',
|
||||
rollupOptions: {
|
||||
rolldownOptions: {
|
||||
external: ['electron', 'custom-electron-prompt', ...builtinModules],
|
||||
input: './src/index.ts',
|
||||
},
|
||||
@ -96,7 +96,7 @@ export default defineConfig({
|
||||
commonjsOptions: {
|
||||
ignoreDynamicRequires: true,
|
||||
},
|
||||
rollupOptions: {
|
||||
rolldownOptions: {
|
||||
external: ['electron', 'custom-electron-prompt', ...builtinModules],
|
||||
input: './src/preload.ts',
|
||||
},
|
||||
@ -149,7 +149,7 @@ export default defineConfig({
|
||||
name: 'renderer',
|
||||
},
|
||||
outDir: 'dist/renderer',
|
||||
rollupOptions: {
|
||||
rolldownOptions: {
|
||||
external: ['electron', ...builtinModules],
|
||||
input: './src/index.html',
|
||||
},
|
||||
|
||||
20
package.json
20
package.json
@ -2,7 +2,7 @@
|
||||
"name": "youtube-music",
|
||||
"desktopName": "com.github.th_ch.youtube_music",
|
||||
"productName": "YouTube Music",
|
||||
"version": "3.10.0",
|
||||
"version": "3.11.0",
|
||||
"description": "YouTube Music Desktop App - including custom plugins",
|
||||
"main": "./dist/main/index.js",
|
||||
"type": "module",
|
||||
@ -20,8 +20,8 @@
|
||||
"vite:inspect": "pnpm clean && electron-vite build --mode development && pnpm exec serve .vite-inspect",
|
||||
"start": "pnpm electron-vite preview",
|
||||
"start:debug": "pnpm cross-env ELECTRON_ENABLE_LOGGING=1 pnpm start",
|
||||
"dev": "pnpm cross-env NODE_OPTIONS=--enable-source-maps electron-vite dev --watch",
|
||||
"dev:renderer": "pnpm cross-env NODE_OPTIONS=--enable-source-maps electron-vite dev",
|
||||
"dev": "pnpm cross-env NODE_ENV=development NODE_OPTIONS=--enable-source-maps electron-vite dev --watch",
|
||||
"dev:renderer": "pnpm cross-env NODE_ENV=development NODE_OPTIONS=--enable-source-maps electron-vite dev",
|
||||
"dev:debug": "pnpm cross-env ELECTRON_ENABLE_LOGGING=1 pnpm dev",
|
||||
"clean": "pnpm del-cli dist && pnpm del-cli pack && pnpm del-cli .vite-inspect",
|
||||
"dist": "pnpm clean && pnpm build && pnpm electron-builder --win --mac --linux -p never",
|
||||
@ -33,7 +33,7 @@
|
||||
"dist:win": "pnpm clean && pnpm build && pnpm electron-builder --win -p never",
|
||||
"dist:win:x64": "pnpm clean && pnpm build && pnpm electron-builder --win nsis-web:x64 -p never",
|
||||
"lint": "pnpm eslint ./src",
|
||||
"changelog": "pnpm dlx --yes auto-changelog",
|
||||
"changelog": "pnpm dlx auto-changelog",
|
||||
"release:linux": "pnpm clean && pnpm build && pnpm electron-builder --linux -p always -c.snap.publish=github",
|
||||
"release:mac": "pnpm clean && pnpm build && pnpm electron-builder --mac -p always",
|
||||
"release:win": "pnpm clean && pnpm build && pnpm electron-builder --win -p always",
|
||||
@ -45,7 +45,7 @@
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"vite": "npm:rolldown-vite@7.1.5",
|
||||
"vite": "npm:rolldown-vite@7.1.8",
|
||||
"node-gyp": "11.4.2",
|
||||
"xml2js": "0.6.2",
|
||||
"node-fetch": "3.3.2",
|
||||
@ -104,7 +104,7 @@
|
||||
"filenamify": "6.0.0",
|
||||
"hanja": "1.1.5",
|
||||
"happy-dom": "18.0.1",
|
||||
"hono": "4.9.6",
|
||||
"hono": "4.9.7",
|
||||
"howler": "2.2.4",
|
||||
"html-to-text": "9.0.5",
|
||||
"i18next": "25.5.2",
|
||||
@ -129,7 +129,7 @@
|
||||
"solid-transition-group": "0.3.0",
|
||||
"tiny-pinyin": "1.3.2",
|
||||
"tinyld": "1.3.4",
|
||||
"virtua": "0.42.2",
|
||||
"virtua": "0.42.3",
|
||||
"vudio": "2.1.1",
|
||||
"x11": "2.3.0",
|
||||
"youtubei.js": "15.0.1",
|
||||
@ -167,11 +167,11 @@
|
||||
"glob": "11.0.3",
|
||||
"node-gyp": "11.4.2",
|
||||
"playwright": "1.55.0",
|
||||
"ts-morph": "26.0.0",
|
||||
"ts-morph": "27.0.0",
|
||||
"typescript": "5.9.2",
|
||||
"typescript-eslint": "8.42.0",
|
||||
"typescript-eslint": "8.43.0",
|
||||
"utf-8-validate": "6.0.5",
|
||||
"vite": "npm:rolldown-vite@7.1.5",
|
||||
"vite": "npm:rolldown-vite@7.1.8",
|
||||
"vite-plugin-inspect": "11.3.3",
|
||||
"vite-plugin-resolve": "2.5.2",
|
||||
"vite-plugin-solid": "2.11.8",
|
||||
|
||||
414
pnpm-lock.yaml
generated
414
pnpm-lock.yaml
generated
@ -5,7 +5,7 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
vite: npm:rolldown-vite@7.1.5
|
||||
vite: npm:rolldown-vite@7.1.8
|
||||
node-gyp: 11.4.2
|
||||
xml2js: 0.6.2
|
||||
node-fetch: 3.3.2
|
||||
@ -235,8 +235,8 @@ importers:
|
||||
specifier: 1.3.4
|
||||
version: 1.3.4
|
||||
virtua:
|
||||
specifier: 0.42.2
|
||||
version: 0.42.2(solid-js@1.9.9)
|
||||
specifier: 0.42.3
|
||||
version: 0.42.3(solid-js@1.9.9)
|
||||
vudio:
|
||||
specifier: 2.1.1
|
||||
version: 2.1.1(patch_hash=0e06c2ed11c02bdc490c209fa80070e98517c2735c641f5738b6e15d7dc1959d)
|
||||
@ -309,7 +309,7 @@ importers:
|
||||
version: 4.0.0
|
||||
electron-vite:
|
||||
specifier: 4.0.0
|
||||
version: 4.0.0(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
version: 4.0.0(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
eslint:
|
||||
specifier: 9.35.0
|
||||
version: 9.35.0
|
||||
@ -324,7 +324,7 @@ importers:
|
||||
version: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.35.0)
|
||||
eslint-plugin-import:
|
||||
specifier: 2.32.0
|
||||
version: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0)
|
||||
version: 2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0)
|
||||
eslint-plugin-prettier:
|
||||
specifier: 5.5.4
|
||||
version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.35.0))(eslint@9.35.0)(prettier@3.6.2)
|
||||
@ -341,29 +341,29 @@ importers:
|
||||
specifier: 1.55.0
|
||||
version: 1.55.0
|
||||
ts-morph:
|
||||
specifier: 26.0.0
|
||||
version: 26.0.0
|
||||
specifier: 27.0.0
|
||||
version: 27.0.0
|
||||
typescript:
|
||||
specifier: 5.9.2
|
||||
version: 5.9.2
|
||||
typescript-eslint:
|
||||
specifier: 8.42.0
|
||||
version: 8.42.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
specifier: 8.43.0
|
||||
version: 8.43.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
utf-8-validate:
|
||||
specifier: 6.0.5
|
||||
version: 6.0.5
|
||||
vite:
|
||||
specifier: npm:rolldown-vite@7.1.5
|
||||
version: rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
specifier: npm:rolldown-vite@7.1.8
|
||||
version: rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vite-plugin-inspect:
|
||||
specifier: 11.3.3
|
||||
version: 11.3.3(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
version: 11.3.3(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
vite-plugin-resolve:
|
||||
specifier: 2.5.2
|
||||
version: 2.5.2
|
||||
vite-plugin-solid:
|
||||
specifier: 2.11.8
|
||||
version: 2.11.8(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))(solid-js@1.9.9)
|
||||
version: 2.11.8(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))(solid-js@1.9.9)
|
||||
ws:
|
||||
specifier: 8.18.3
|
||||
version: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
@ -1062,12 +1062,12 @@ packages:
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
deprecated: This functionality has been moved to @npmcli/fs
|
||||
|
||||
'@oxc-project/runtime@0.82.3':
|
||||
resolution: {integrity: sha512-LNh5GlJvYHAnMurO+EyA8jJwN1rki7l3PSHuosDh2I7h00T6/u9rCkUjg/SvPmT1CZzvhuW0y+gf7jcqUy/Usg==}
|
||||
'@oxc-project/runtime@0.87.0':
|
||||
resolution: {integrity: sha512-ky2Hqi2q/uGX36UfY79zxMbUqiNIl1RyKKVJfFenG70lbn+/fcaKBVTbhmUwn8a2wPyv2gNtDQxuDytbKX9giQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@oxc-project/types@0.82.3':
|
||||
resolution: {integrity: sha512-6nCUxBnGX0c6qfZW5MaF6/fmu5dHJDMiMPaioKHKs5mi5+8/FHQ7WGjgQIz1zxpmceMYfdIXkOaLYE+ejbuOtA==}
|
||||
'@oxc-project/types@0.87.0':
|
||||
resolution: {integrity: sha512-ipZFWVGE9fADBVXXWJWY/cxpysc41Gt5upKDeb32F6WMgFyO7XETUMVq8UuREKCih+Km5E6p2VhEvf6Fuhey6g==}
|
||||
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
@ -1103,78 +1103,91 @@ packages:
|
||||
'@remusao/trie@2.1.0':
|
||||
resolution: {integrity: sha512-Er3Q8q0/2OcCJPQYJOPLmCuqO0wu7cav3SPtpjlxSbjFi1x+A1pZkkLD6c9q2rGEkGW/tkrRzfrhNMt8VQjzXg==}
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-jf5GNe5jP3Sr1Tih0WKvg2bzvh5T/1TA0fn1u32xSH7ca/p5t+/QRr4VRFCV/na5vjwKEhwWrChsL2AWlY+eoA==}
|
||||
'@rolldown/binding-android-arm64@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-0y4+MDSw9GzX4VZtATiygDv+OtijxsRtNBZW6qA3OUGi0fq6Gq+MnvFHMjdJxz3mv/thIHMmJ0AL7d8urYBCUw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-2F/TqH4QuJQ34tgWxqBjFL3XV1gMzeQgUO8YRtCPGBSP0GhxtoFzsp7KqmQEothsxztlv+KhhT9Dbg3HHwHViQ==}
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-F/xv0vsxXuwpyecy3GMpXPhRLI4WogQkSYYl6hh61OfmyX4lxsemSoYQ5nlK/MopdVaT111wS1dRO2eXgzBHuA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-E1QuFslgLWbHQ8Qli/AqUKdfg0pockQPwRxVbhNQ74SciZEZpzLaujkdmOLSccMlSXDfFCF8RPnMoRAzQ9JV8Q==}
|
||||
'@rolldown/binding-darwin-x64@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-FX3x/GSybYRt4/fUljqIMuB7JRJThxnwzjK9Ka4qKwSw92RNmxRtw+NEkpuKq/Tzcq5qpnvSWudKmjcbBSMH1g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-VS8VInNCwnkpI9WeQaWu3kVBq9ty6g7KrHdLxYMzeqz24+w9hg712TcWdqzdY6sn+24lUoMD9jTZrZ/qfVpk0g==}
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-j7Y/OG4XxICRgGMLB7VVbROAzdnvtr0ZTBBYnv53KZESE97Ta4zXfGhEe+EiXLRKW8JWSMeNumOaBrWAXDMiZQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-4St4emjcnULnxJYb/5ZDrH/kK/j6PcUgc3eAqH5STmTrcF+I9m/X2xvSF2a2bWv1DOQhxBewThu0KkwGHdgu5w==}
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-j3rDknokIJZ+iVGjWw2cVRgKLmk9boUoHtp2k3Ba6p7vWIv+D/YypQKHxAayyzvUkxTBZsw64Ojq5/zrytRODA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-a737FTqhFUoWfnebS2SnQ2BS50p0JdukdkUBwy2J06j4hZ6Eej0zEB8vTfAqoCjn8BQKkXBy+3Sx0IRkgwz1gA==}
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-7Ds2nl3ZhC0eaSJnw7dQ5uCK1cmaBKC+EL7IIpjTpzqY10y1xCn5w6gTFKzpqKhD2nSraY4MHOyAnE+zmSAZRA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-NH+FeQWKyuw0k+PbXqpFWNfvD8RPvfJk766B/njdaWz4TmiEcSB0Nb6guNw1rBpM1FmltQYb3fFnTumtC6pRfA==}
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-0Qa4b3gv956iSdJQplV1xdI9ALbEdNo5xsFpcLU4mW2A+CqWNenVHqcHbCvwvKTP07yX6yoUvUqZR1CBxxQShg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-Q3RSCivp8pNadYK8ke3hLnQk08BkpZX9BmMjgwae2FWzdxhxxUiUzd9By7kneUL0vRQ4uRnhD9VkFQ+Haeqdvw==}
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-wUdZljtx9W1V9KlnmwPgF0o2ZPFq2zffr/q+wM+GUrSFIJNmP9w0zgyl1coCt1ESnNyYYyJh8T1bqvx8+16SqA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-wDd/HrNcVoBhWWBUW3evJHoo7GJE/RofssBy3Dsiip05YUBmokQVrYAyrboOY4dzs/lJ7HYeBtWQ9hj8wlyF0A==}
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-Up56sJMDSKYi92/28lq9xB2wonuCwVnqBzjRnKmQauZJ5QOor9h1RtcMeCzSxg4ReMsNvrdYomBogewcZgKEww==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-dH3FTEV6KTNWpYSgjSXZzeX7vLty9oBYn6R3laEdhwZftQwq030LKL+5wyQdlbX5pnbh4h127hpv3Hl1+sj8dg==}
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-qX3covX7EX00yrgQl3oi8GuRTS1XFe+YHm+sGsxQvPok+r7Ct2eDFpLmmw7wajZ2SuvAJYSo/9BXLSCGR0ve2w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-y5BUf+QtO0JsIDKA51FcGwvhJmv89BYjUl8AmN7jqD6k/eU55mH6RJYnxwCsODq5m7KSSTigVb6O7/GqB8wbPw==}
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-phFsiR97/nbQEtyo5GTPX4h/Ootz0Pdd7P7+gTmkiashePwPUik5aoMAluvzY1tTUAfhdrFR2Y8WiWbnxnsSrQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-ga5hFhdTwpaNxEiuxZHWnD3ed0GBAzbgzS5tRHpe0ObptxM1a9Xrq6TVfNQirBLwb5Y7T/FJmJi3pmdLy95ljg==}
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-dvvByfl7TRVhD9zY/VJ94hOVJmpN8Cfxl/A77yJ/oKV67IPEXx9hRUIhuL/V9eJ0RphNbLo4VKxdVuZ+wzEWTA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-4/MBp9T9eRnZskxWr8EXD/xHvLhdjWaeX/qY9LPRG1JdCGV3DphkLTy5AWwIQ5jhAy2ZNJR5z2fYRlpWU0sIyQ==}
|
||||
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-n7odfY4zatppNGY/EE8wE8B78wIxlQzBaY7Ycyjun+HvYu4dJgz8A4JCKHhyYYoEA8+VXO167Or4EJ9SyBLNnw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-7O5iUBX6HSBKlQU4WykpUoEmb0wQmonb6ziKFr3dJTHud2kzDnWMqk344T0qm3uGv9Ddq6Re/94pInxo1G2d4w==}
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-ik9dlOa/bhRk+8NmbqCEZm9BBPy5UfSOg/Y6cAQac29Aw2/uoyoBbFUBFUKMsvfLg8F0dNxUOsT3IcVlfOJu0g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-beta.34':
|
||||
resolution: {integrity: sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==}
|
||||
'@rolldown/pluginutils@1.0.0-beta.36':
|
||||
resolution: {integrity: sha512-qa+gfzhv0/Xv52zZInENLu6JbsnSjSExD7kTaNm7Qn5LUIH6IQb7l9pB+NrsU5/Bvt9aqcBTdRGc7x1DYMTiqQ==}
|
||||
|
||||
'@rtsao/scc@1.1.0':
|
||||
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
|
||||
@ -1237,8 +1250,8 @@ packages:
|
||||
'@total-typescript/ts-reset@0.6.1':
|
||||
resolution: {integrity: sha512-cka47fVSo6lfQDIATYqb/vO1nvFfbPw7uWLayIXIhGETj0wcOOlrlkobOMDNQOFr9QOafegUPq13V2+6vtD7yg==}
|
||||
|
||||
'@ts-morph/common@0.27.0':
|
||||
resolution: {integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==}
|
||||
'@ts-morph/common@0.28.0':
|
||||
resolution: {integrity: sha512-4w6X/oFmvXcwux6y6ExfM/xSqMHw20cYwFJH+BlYrtGa6nwY9qGq8GXnUs1sVYeF2o/KT3S8hAH6sKBI3VOkBg==}
|
||||
|
||||
'@tybys/wasm-util@0.10.0':
|
||||
resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==}
|
||||
@ -1324,16 +1337,16 @@ packages:
|
||||
'@types/yauzl@2.10.3':
|
||||
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.42.0':
|
||||
resolution: {integrity: sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==}
|
||||
'@typescript-eslint/eslint-plugin@8.43.0':
|
||||
resolution: {integrity: sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^8.42.0
|
||||
'@typescript-eslint/parser': ^8.43.0
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/parser@8.42.0':
|
||||
resolution: {integrity: sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==}
|
||||
'@typescript-eslint/parser@8.43.0':
|
||||
resolution: {integrity: sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@ -1345,18 +1358,34 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/project-service@8.43.0':
|
||||
resolution: {integrity: sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/scope-manager@8.42.0':
|
||||
resolution: {integrity: sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/scope-manager@8.43.0':
|
||||
resolution: {integrity: sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.42.0':
|
||||
resolution: {integrity: sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/type-utils@8.42.0':
|
||||
resolution: {integrity: sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==}
|
||||
'@typescript-eslint/tsconfig-utils@8.43.0':
|
||||
resolution: {integrity: sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/type-utils@8.43.0':
|
||||
resolution: {integrity: sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@ -1366,12 +1395,22 @@ packages:
|
||||
resolution: {integrity: sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/types@8.43.0':
|
||||
resolution: {integrity: sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.42.0':
|
||||
resolution: {integrity: sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.43.0':
|
||||
resolution: {integrity: sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/utils@8.42.0':
|
||||
resolution: {integrity: sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
@ -1379,10 +1418,21 @@ packages:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/utils@8.43.0':
|
||||
resolution: {integrity: sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.42.0':
|
||||
resolution: {integrity: sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.43.0':
|
||||
resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@unrs/resolver-binding-android-arm-eabi@1.11.1':
|
||||
resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==}
|
||||
cpu: [arm]
|
||||
@ -3997,8 +4047,8 @@ packages:
|
||||
resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==}
|
||||
engines: {node: '>=8.0'}
|
||||
|
||||
rolldown-vite@7.1.5:
|
||||
resolution: {integrity: sha512-NgHjKatQn1B5TjtNVS3+Uq3JBUPP8s70cMxLzGHpv/UyCGj0SQUtVYImNWbU2uqfOpNSnqhI+nbR7tmPPcb1qQ==}
|
||||
rolldown-vite@7.1.8:
|
||||
resolution: {integrity: sha512-AfI/iNNsTjJv6E3nUSAra8bP4j30MZTt8JSB6iBZP1dblxnF6+3EE6TXQc75M69aH/Cr5p6N1Sk/1JyTDKFgOg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -4037,8 +4087,9 @@ packages:
|
||||
yaml:
|
||||
optional: true
|
||||
|
||||
rolldown@1.0.0-beta.34:
|
||||
resolution: {integrity: sha512-Wwh7EwalMzzX3Yy3VN58VEajeR2Si8+HDNMf706jPLIqU7CxneRW+dQVfznf5O0TWTnJyu4npelwg2bzTXB1Nw==}
|
||||
rolldown@1.0.0-beta.36:
|
||||
resolution: {integrity: sha512-eethnJ/UfQWg2VWBDDMEu7IDvEh4WPbPb1azPWDCHcuOwoPT9C2NT4Y/ecZztCl9OBzXoA+CXXb5MS+qbukAig==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
run-applescript@7.0.0:
|
||||
@ -4391,6 +4442,10 @@ packages:
|
||||
resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
tinyld@1.3.4:
|
||||
resolution: {integrity: sha512-u26CNoaInA4XpDU+8s/6Cq8xHc2T5M4fXB3ICfXPokUQoLzmPgSZU02TAkFwFMJCWTjk53gtkS8pETTreZwCqw==}
|
||||
engines: {node: '>= 12.10.0', npm: '>= 6.12.0', yarn: '>= 1.20.0'}
|
||||
@ -4430,8 +4485,8 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4'
|
||||
|
||||
ts-morph@26.0.0:
|
||||
resolution: {integrity: sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==}
|
||||
ts-morph@27.0.0:
|
||||
resolution: {integrity: sha512-xcqelpTR5PCuZMs54qp9DE3t7tPgA2v/P1/qdW4ke5b3Y5liTGTYj6a/twT35EQW/H5okRqp1UOqwNlgg0K0eQ==}
|
||||
|
||||
tsconfig-paths@3.15.0:
|
||||
resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
|
||||
@ -4471,8 +4526,8 @@ packages:
|
||||
resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
typescript-eslint@8.42.0:
|
||||
resolution: {integrity: sha512-ozR/rQn+aQXQxh1YgbCzQWDFrsi9mcg+1PM3l/z5o1+20P7suOIaNg515bpr/OYt6FObz/NHcBstydDLHWeEKg==}
|
||||
typescript-eslint@8.43.0:
|
||||
resolution: {integrity: sha512-FyRGJKUGvcFekRRcBKFBlAhnp4Ng8rhe8tuvvkR9OiU0gfd4vyvTRQHEckO6VDlH57jbeUQem2IpqPq9kLJH+w==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@ -4579,8 +4634,8 @@ packages:
|
||||
resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==}
|
||||
engines: {node: '>=0.6.0'}
|
||||
|
||||
virtua@0.42.2:
|
||||
resolution: {integrity: sha512-9ZQ1HtN6IhJ9tEG6NenjbcSPGpnbd8QeHLEjPadZ1rMVX7T4g+9QybetSeECNq2q2sXh799xw4mrMCYKx4HXmQ==}
|
||||
virtua@0.42.3:
|
||||
resolution: {integrity: sha512-5FoAKcEvh05qsUF97Yz42SWJ7bwnPExjUYHGuoxz1EUtfWtaOgXaRwnylJbDpA0QcH1rKvJ2qsGRi9MK1fpQbg==}
|
||||
peerDependencies:
|
||||
react: '>=16.14.0'
|
||||
react-dom: '>=16.14.0'
|
||||
@ -5618,9 +5673,9 @@ snapshots:
|
||||
mkdirp: 1.0.4
|
||||
rimraf: 3.0.2
|
||||
|
||||
'@oxc-project/runtime@0.82.3': {}
|
||||
'@oxc-project/runtime@0.87.0': {}
|
||||
|
||||
'@oxc-project/types@0.82.3': {}
|
||||
'@oxc-project/types@0.87.0': {}
|
||||
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
@ -5650,51 +5705,51 @@ snapshots:
|
||||
|
||||
'@remusao/trie@2.1.0': {}
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-beta.34':
|
||||
'@rolldown/binding-android-arm64@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-beta.34':
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.0.0-beta.34':
|
||||
'@rolldown/binding-darwin-x64@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-beta.34':
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.34':
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.34':
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.34':
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.34':
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-beta.34':
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-beta.34':
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-beta.34':
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-beta.36':
|
||||
dependencies:
|
||||
'@napi-rs/wasm-runtime': 1.0.3
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.34':
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.34':
|
||||
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.34':
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.36':
|
||||
optional: true
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-beta.34': {}
|
||||
'@rolldown/pluginutils@1.0.0-beta.36': {}
|
||||
|
||||
'@rtsao/scc@1.1.0': {}
|
||||
|
||||
@ -5746,11 +5801,11 @@ snapshots:
|
||||
|
||||
'@total-typescript/ts-reset@0.6.1': {}
|
||||
|
||||
'@ts-morph/common@0.27.0':
|
||||
'@ts-morph/common@0.28.0':
|
||||
dependencies:
|
||||
fast-glob: 3.3.3
|
||||
minimatch: 10.0.3
|
||||
path-browserify: 1.0.1
|
||||
tinyglobby: 0.2.14
|
||||
|
||||
'@tybys/wasm-util@0.10.0':
|
||||
dependencies:
|
||||
@ -5855,14 +5910,14 @@ snapshots:
|
||||
'@types/node': 24.3.0
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2)':
|
||||
'@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@typescript-eslint/parser': 8.42.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/scope-manager': 8.42.0
|
||||
'@typescript-eslint/type-utils': 8.42.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/utils': 8.42.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/visitor-keys': 8.42.0
|
||||
'@typescript-eslint/parser': 8.43.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/scope-manager': 8.43.0
|
||||
'@typescript-eslint/type-utils': 8.43.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/utils': 8.43.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/visitor-keys': 8.43.0
|
||||
eslint: 9.35.0
|
||||
graphemer: 1.4.0
|
||||
ignore: 7.0.5
|
||||
@ -5872,12 +5927,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@5.9.2)':
|
||||
'@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.42.0
|
||||
'@typescript-eslint/types': 8.42.0
|
||||
'@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2)
|
||||
'@typescript-eslint/visitor-keys': 8.42.0
|
||||
'@typescript-eslint/scope-manager': 8.43.0
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/visitor-keys': 8.43.0
|
||||
debug: 4.4.1
|
||||
eslint: 9.35.0
|
||||
typescript: 5.9.2
|
||||
@ -5893,20 +5948,38 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/project-service@8.43.0(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
debug: 4.4.1
|
||||
typescript: 5.9.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/scope-manager@8.42.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.42.0
|
||||
'@typescript-eslint/visitor-keys': 8.42.0
|
||||
|
||||
'@typescript-eslint/scope-manager@8.43.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
'@typescript-eslint/visitor-keys': 8.43.0
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.42.0(typescript@5.9.2)':
|
||||
dependencies:
|
||||
typescript: 5.9.2
|
||||
|
||||
'@typescript-eslint/type-utils@8.42.0(eslint@9.35.0)(typescript@5.9.2)':
|
||||
'@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.42.0
|
||||
'@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2)
|
||||
'@typescript-eslint/utils': 8.42.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
typescript: 5.9.2
|
||||
|
||||
'@typescript-eslint/type-utils@8.43.0(eslint@9.35.0)(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/utils': 8.43.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
debug: 4.4.1
|
||||
eslint: 9.35.0
|
||||
ts-api-utils: 2.1.0(typescript@5.9.2)
|
||||
@ -5916,6 +5989,8 @@ snapshots:
|
||||
|
||||
'@typescript-eslint/types@8.42.0': {}
|
||||
|
||||
'@typescript-eslint/types@8.43.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.42.0(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@typescript-eslint/project-service': 8.42.0(typescript@5.9.2)
|
||||
@ -5932,6 +6007,22 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.43.0(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@typescript-eslint/project-service': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
'@typescript-eslint/visitor-keys': 8.43.0
|
||||
debug: 4.4.1
|
||||
fast-glob: 3.3.3
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.5
|
||||
semver: 7.7.2
|
||||
ts-api-utils: 2.1.0(typescript@5.9.2)
|
||||
typescript: 5.9.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.42.0(eslint@9.35.0)(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.8.0(eslint@9.35.0)
|
||||
@ -5943,11 +6034,27 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.43.0(eslint@9.35.0)(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.8.0(eslint@9.35.0)
|
||||
'@typescript-eslint/scope-manager': 8.43.0
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
|
||||
eslint: 9.35.0
|
||||
typescript: 5.9.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.42.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.42.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.43.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@unrs/resolver-binding-android-arm-eabi@1.11.1':
|
||||
optional: true
|
||||
|
||||
@ -6928,7 +7035,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
electron-vite@4.0.0(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
electron-vite@4.0.0(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.3
|
||||
'@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.3)
|
||||
@ -6936,7 +7043,7 @@ snapshots:
|
||||
esbuild: 0.25.9
|
||||
magic-string: 0.30.17
|
||||
picocolors: 1.1.1
|
||||
vite: rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vite: rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@ -7135,7 +7242,7 @@ snapshots:
|
||||
eslint-import-resolver-exports@1.0.0-beta.5(eslint-plugin-import@2.32.0)(eslint@9.35.0):
|
||||
dependencies:
|
||||
eslint: 9.35.0
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0)
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0)
|
||||
resolve.exports: 2.0.3
|
||||
|
||||
eslint-import-resolver-node@0.3.9:
|
||||
@ -7157,22 +7264,22 @@ snapshots:
|
||||
tinyglobby: 0.2.14
|
||||
unrs-resolver: 1.11.1
|
||||
optionalDependencies:
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0)
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0):
|
||||
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.42.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/parser': 8.43.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
eslint: 9.35.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.35.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0):
|
||||
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0):
|
||||
dependencies:
|
||||
'@rtsao/scc': 1.1.0
|
||||
array-includes: 3.1.9
|
||||
@ -7183,7 +7290,7 @@ snapshots:
|
||||
doctrine: 2.1.0
|
||||
eslint: 9.35.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0)
|
||||
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0)
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.16.1
|
||||
is-glob: 4.0.3
|
||||
@ -7195,7 +7302,7 @@ snapshots:
|
||||
string.prototype.trimend: 1.0.9
|
||||
tsconfig-paths: 3.15.0
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.42.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/parser': 8.43.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-typescript
|
||||
- eslint-import-resolver-webpack
|
||||
@ -8835,41 +8942,41 @@ snapshots:
|
||||
sprintf-js: 1.1.3
|
||||
optional: true
|
||||
|
||||
rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1):
|
||||
rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1):
|
||||
dependencies:
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
lightningcss: 1.30.1
|
||||
picomatch: 4.0.3
|
||||
postcss: 8.5.6
|
||||
rolldown: 1.0.0-beta.34
|
||||
tinyglobby: 0.2.14
|
||||
rolldown: 1.0.0-beta.36
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
'@types/node': 24.3.0
|
||||
esbuild: 0.25.9
|
||||
fsevents: 2.3.3
|
||||
yaml: 2.8.1
|
||||
|
||||
rolldown@1.0.0-beta.34:
|
||||
rolldown@1.0.0-beta.36:
|
||||
dependencies:
|
||||
'@oxc-project/runtime': 0.82.3
|
||||
'@oxc-project/types': 0.82.3
|
||||
'@rolldown/pluginutils': 1.0.0-beta.34
|
||||
'@oxc-project/runtime': 0.87.0
|
||||
'@oxc-project/types': 0.87.0
|
||||
'@rolldown/pluginutils': 1.0.0-beta.36
|
||||
ansis: 4.1.0
|
||||
optionalDependencies:
|
||||
'@rolldown/binding-android-arm64': 1.0.0-beta.34
|
||||
'@rolldown/binding-darwin-arm64': 1.0.0-beta.34
|
||||
'@rolldown/binding-darwin-x64': 1.0.0-beta.34
|
||||
'@rolldown/binding-freebsd-x64': 1.0.0-beta.34
|
||||
'@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.34
|
||||
'@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.34
|
||||
'@rolldown/binding-linux-arm64-musl': 1.0.0-beta.34
|
||||
'@rolldown/binding-linux-x64-gnu': 1.0.0-beta.34
|
||||
'@rolldown/binding-linux-x64-musl': 1.0.0-beta.34
|
||||
'@rolldown/binding-openharmony-arm64': 1.0.0-beta.34
|
||||
'@rolldown/binding-wasm32-wasi': 1.0.0-beta.34
|
||||
'@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.34
|
||||
'@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.34
|
||||
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.34
|
||||
'@rolldown/binding-android-arm64': 1.0.0-beta.36
|
||||
'@rolldown/binding-darwin-arm64': 1.0.0-beta.36
|
||||
'@rolldown/binding-darwin-x64': 1.0.0-beta.36
|
||||
'@rolldown/binding-freebsd-x64': 1.0.0-beta.36
|
||||
'@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.36
|
||||
'@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.36
|
||||
'@rolldown/binding-linux-arm64-musl': 1.0.0-beta.36
|
||||
'@rolldown/binding-linux-x64-gnu': 1.0.0-beta.36
|
||||
'@rolldown/binding-linux-x64-musl': 1.0.0-beta.36
|
||||
'@rolldown/binding-openharmony-arm64': 1.0.0-beta.36
|
||||
'@rolldown/binding-wasm32-wasi': 1.0.0-beta.36
|
||||
'@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.36
|
||||
'@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.36
|
||||
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.36
|
||||
|
||||
run-applescript@7.0.0: {}
|
||||
|
||||
@ -9278,6 +9385,11 @@ snapshots:
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
picomatch: 4.0.3
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
dependencies:
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
picomatch: 4.0.3
|
||||
|
||||
tinyld@1.3.4: {}
|
||||
|
||||
tldts-core@7.0.12: {}
|
||||
@ -9311,9 +9423,9 @@ snapshots:
|
||||
dependencies:
|
||||
typescript: 5.9.2
|
||||
|
||||
ts-morph@26.0.0:
|
||||
ts-morph@27.0.0:
|
||||
dependencies:
|
||||
'@ts-morph/common': 0.27.0
|
||||
'@ts-morph/common': 0.28.0
|
||||
code-block-writer: 13.0.3
|
||||
|
||||
tsconfig-paths@3.15.0:
|
||||
@ -9369,12 +9481,12 @@ snapshots:
|
||||
possible-typed-array-names: 1.1.0
|
||||
reflect.getprototypeof: 1.0.10
|
||||
|
||||
typescript-eslint@8.42.0(eslint@9.35.0)(typescript@5.9.2):
|
||||
typescript-eslint@8.43.0(eslint@9.35.0)(typescript@5.9.2):
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/parser': 8.42.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2)
|
||||
'@typescript-eslint/utils': 8.42.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/parser': 8.43.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/utils': 8.43.0(eslint@9.35.0)(typescript@5.9.2)
|
||||
eslint: 9.35.0
|
||||
typescript: 5.9.2
|
||||
transitivePeerDependencies:
|
||||
@ -9494,21 +9606,21 @@ snapshots:
|
||||
extsprintf: 1.4.1
|
||||
optional: true
|
||||
|
||||
virtua@0.42.2(solid-js@1.9.9):
|
||||
virtua@0.42.3(solid-js@1.9.9):
|
||||
optionalDependencies:
|
||||
solid-js: 1.9.9
|
||||
|
||||
vite-dev-rpc@1.1.0(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
vite-dev-rpc@1.1.0(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
dependencies:
|
||||
birpc: 2.5.0
|
||||
vite: rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vite-hot-client: 2.1.0(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
vite: rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vite-hot-client: 2.1.0(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
|
||||
vite-hot-client@2.1.0(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
vite-hot-client@2.1.0(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
dependencies:
|
||||
vite: rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vite: rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
|
||||
vite-plugin-inspect@11.3.3(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
vite-plugin-inspect@11.3.3(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
dependencies:
|
||||
ansis: 4.1.0
|
||||
debug: 4.4.1
|
||||
@ -9518,8 +9630,8 @@ snapshots:
|
||||
perfect-debounce: 2.0.0
|
||||
sirv: 3.0.1
|
||||
unplugin-utils: 0.3.0
|
||||
vite: rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vite-dev-rpc: 1.1.0(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
vite: rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vite-dev-rpc: 1.1.0(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@ -9527,7 +9639,7 @@ snapshots:
|
||||
dependencies:
|
||||
lib-esm: 0.4.2
|
||||
|
||||
vite-plugin-solid@2.11.8(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))(solid-js@1.9.9):
|
||||
vite-plugin-solid@2.11.8(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))(solid-js@1.9.9):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.3
|
||||
'@types/babel__core': 7.20.5
|
||||
@ -9535,14 +9647,14 @@ snapshots:
|
||||
merge-anything: 5.1.7
|
||||
solid-js: 1.9.9
|
||||
solid-refresh: 0.6.3(solid-js@1.9.9)
|
||||
vite: rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vitefu: 1.1.1(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
vite: rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vitefu: 1.1.1(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1))
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vitefu@1.1.1(rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
vitefu@1.1.1(rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)):
|
||||
optionalDependencies:
|
||||
vite: rolldown-vite@7.1.5(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
vite: rolldown-vite@7.1.8(@types/node@24.3.0)(esbuild@0.25.9)(yaml@2.8.1)
|
||||
|
||||
vudio@2.1.1(patch_hash=0e06c2ed11c02bdc490c209fa80070e98517c2735c641f5738b6e15d7dc1959d): {}
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ export interface DefaultConfig {
|
||||
'plugins': Record<string, unknown>;
|
||||
}
|
||||
|
||||
const defaultConfig: DefaultConfig = {
|
||||
export const defaultConfig: DefaultConfig = {
|
||||
'window-size': {
|
||||
width: 1100,
|
||||
height: 550,
|
||||
@ -74,5 +74,3 @@ const defaultConfig: DefaultConfig = {
|
||||
},
|
||||
'plugins': {},
|
||||
};
|
||||
|
||||
export default defaultConfig;
|
||||
|
||||
@ -1,30 +1,36 @@
|
||||
import { deepmergeCustom } from 'deepmerge-ts';
|
||||
|
||||
import defaultConfig from './defaults';
|
||||
|
||||
import store, { type IStore } from './store';
|
||||
import plugins from './plugins';
|
||||
|
||||
import { store, type IStore } from './store';
|
||||
import { restart } from '@/providers/app-controls';
|
||||
|
||||
import type { defaultConfig } from './defaults';
|
||||
|
||||
const deepmerge = deepmergeCustom({
|
||||
mergeArrays: false,
|
||||
});
|
||||
|
||||
const set = (key: string, value: unknown) => {
|
||||
export { defaultConfig } from './defaults';
|
||||
export * as plugins from './plugins';
|
||||
|
||||
export const set = (key: string, value: unknown) => {
|
||||
store.set(key, value);
|
||||
};
|
||||
const setPartial = (key: string, value: object, defaultValue?: object) => {
|
||||
|
||||
export const setPartial = (
|
||||
key: string,
|
||||
value: object,
|
||||
defaultValue?: object,
|
||||
) => {
|
||||
const newValue = deepmerge(defaultValue ?? {}, store.get(key) ?? {}, value);
|
||||
store.set(key, newValue);
|
||||
};
|
||||
|
||||
function setMenuOption(key: string, value: unknown) {
|
||||
export const setMenuOption = (key: string, value: unknown) => {
|
||||
set(key, value);
|
||||
if (store.get('options.restartOnConfigChanges')) {
|
||||
restart();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// MAGIC OF TYPESCRIPT
|
||||
|
||||
@ -74,18 +80,11 @@ type PathValue<T, K extends string> =
|
||||
? PathValue<T[A], B>
|
||||
: T;
|
||||
|
||||
const get = <Key extends Paths<typeof defaultConfig>>(key: Key) =>
|
||||
export const get = <Key extends Paths<typeof defaultConfig>>(key: Key) =>
|
||||
store.get(key) as PathValue<typeof defaultConfig, typeof key>;
|
||||
|
||||
export default {
|
||||
defaultConfig,
|
||||
get,
|
||||
set,
|
||||
setPartial,
|
||||
setMenuOption,
|
||||
edit: () => store.openInEditor(),
|
||||
watch(cb: Parameters<IStore['onDidAnyChange']>[0]) {
|
||||
store.onDidAnyChange(cb);
|
||||
},
|
||||
plugins,
|
||||
export const edit = () => store.openInEditor();
|
||||
|
||||
export const watch = (cb: Parameters<IStore['onDidAnyChange']>[0]) => {
|
||||
store.onDidAnyChange(cb);
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { deepmerge } from 'deepmerge-ts';
|
||||
import { allPlugins } from 'virtual:plugins';
|
||||
|
||||
import store from './store';
|
||||
import { store } from './store';
|
||||
|
||||
import { restart } from '@/providers/app-controls';
|
||||
|
||||
@ -68,13 +68,3 @@ export function enable(plugin: string) {
|
||||
export function disable(plugin: string) {
|
||||
setMenuOptions(plugin, { enabled: false }, []);
|
||||
}
|
||||
|
||||
export default {
|
||||
isEnabled,
|
||||
getPlugins,
|
||||
enable,
|
||||
disable,
|
||||
setOptions,
|
||||
setMenuOptions,
|
||||
getOptions,
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import Store from 'electron-store';
|
||||
|
||||
import defaults from './defaults';
|
||||
import { defaultConfig as defaults } from './defaults';
|
||||
|
||||
import { DefaultPresetList, type Preset } from '@/plugins/downloader/types';
|
||||
|
||||
@ -257,7 +257,7 @@ const migrations = {
|
||||
},
|
||||
};
|
||||
|
||||
export default new Store({
|
||||
export const store = new Store({
|
||||
defaults: {
|
||||
...defaults,
|
||||
// README: 'plugin' uses deepmerge to populate the default values, so it is not necessary to include it here
|
||||
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "Configura un dispositiu multimèdia de sortida personalitzat per a cançons",
|
||||
"menu": {
|
||||
"device-selector": "Selecciona un dispositiu"
|
||||
},
|
||||
"name": "Dispositiu de sortida personalitzat",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Trieu el dispositiu de sortida que s'utilitzarà",
|
||||
"title": "Escull el dispositiu de sortida"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Fa que la cançó comenci en mode «pausat»",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "Amaga la durada restant",
|
||||
"hide-github-button": "Amaga el botó de l'enllaç a GitHub",
|
||||
"play-on-youtube-music": "Reprodueix a YouTube Music",
|
||||
"set-inactivity-timeout": "Estableix temps d'espera d'inactivitat"
|
||||
"set-inactivity-timeout": "Estableix temps d'espera d'inactivitat",
|
||||
"set-status-display-type": {
|
||||
"label": "Text d'estat",
|
||||
"submenu": {
|
||||
"artist": "Escoltant {artist}",
|
||||
"title": "Escoltant {song title}",
|
||||
"youtube-music": "Escoltant YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Estat d'activitat de Discord",
|
||||
"prompt": {
|
||||
@ -615,10 +636,10 @@
|
||||
"name": "Navegació",
|
||||
"templates": {
|
||||
"back": {
|
||||
"title": "Tornar a la pàgina anterior"
|
||||
"title": "Pàgina anterior"
|
||||
},
|
||||
"forward": {
|
||||
"title": "Anar a la pàgina següent"
|
||||
"title": "Pàgina següent"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Introduir token d'usuari de ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Utilitza artistes alternatius",
|
||||
"scrobble-alternative-title": "Useu títols alternatius",
|
||||
"scrobble-other-media": "Scrobble amb altres mitjans"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "Fes que les lletres es sincronitzin a la perfecció",
|
||||
"tooltip": "Calcula al mil·lisegon l'aparició de la següent línia (pot tenir un petit impacte en el rendiment)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Proveïdor preferit",
|
||||
"none": {
|
||||
"label": "Cap",
|
||||
"tooltip": "Cap proveïdor preferit"
|
||||
},
|
||||
"tooltip": "Trieu el proveïdor predeterminat que voleu utilitzar"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Romanitza les lletres",
|
||||
"tooltip": "Si les lletres són en un idioma diferent, intenta mostrar la versió amb alfabet llatí."
|
||||
@ -853,6 +883,9 @@
|
||||
"description": "Afegeix un giny a la Touch Bar per usuaris de macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Fa la finestra de l'aplicació transparent"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integració amb l'extensió «Tuna» del OBS",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
"load-all": "Načítání všech pluginů",
|
||||
"load-failed": "Selhalo načtení \"{{pluginName}}\" pluginu",
|
||||
"loaded": "Plugin \"{{pluginName}}\" načten",
|
||||
"unload-failed": "Selhalo unload \"{{pluginName}}\" pluginu",
|
||||
"unload-failed": "Selhalo vypnutí \"{{pluginName}}\" pluginu",
|
||||
"unloaded": "Plugin {{pluginName}} byl odnačten"
|
||||
}
|
||||
}
|
||||
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "Einen maßgeschneiderten Ausgabemedienträger für Lieder einrichten",
|
||||
"menu": {
|
||||
"device-selector": "Gerät auswählen"
|
||||
},
|
||||
"name": "Benutzerdefiniertes Ausgabegerät",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Wähle das Ausgabegerät, welches benutzt werden soll",
|
||||
"title": "Wähle ein Ausgabegerät"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Startet Lied im pausierten Modus",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "Verbleibende Zeit verstecken",
|
||||
"hide-github-button": "Knopf mit Link zu GitHub ausblenden",
|
||||
"play-on-youtube-music": "Auf YouTube Music abspielen",
|
||||
"set-inactivity-timeout": "Inaktivitätstimeout setzen"
|
||||
"set-inactivity-timeout": "Inaktivitätstimeout setzen",
|
||||
"set-status-display-type": {
|
||||
"label": "Status Text",
|
||||
"submenu": {
|
||||
"artist": "Hört {artist} zu",
|
||||
"title": "Du hörst {song title}",
|
||||
"youtube-music": "Hört YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discords Aktivitätsstatus",
|
||||
"prompt": {
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "ListenBrainz-Benutzer-Token eintragen"
|
||||
},
|
||||
"scrobble-alternative-artist": "Benutze Alternative Künstler",
|
||||
"scrobble-alternative-title": "Nutze alternative Titel",
|
||||
"scrobble-other-media": "Andere Medien scrobbeln"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "Den Songtext perfekt synchronisieren",
|
||||
"tooltip": "Auf die Millisekunde genau berechnen, wann die nächste Zeile angezeigt werden soll (Kann Einfluss auf die Leistung haben)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "bevorzugter Anbieter",
|
||||
"none": {
|
||||
"label": "Nichts",
|
||||
"tooltip": "Kein bevorzugter Anbieter"
|
||||
},
|
||||
"tooltip": "Standardanbieter auswählen"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Lateinische Umschrift anzeigen",
|
||||
"tooltip": "Wenn der Liedtext in einer anderen Schrift ist, zeige nach Möglichkeit eine Version in lateinischer Schrift an."
|
||||
@ -855,7 +885,6 @@
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Macht das Player-Fenster transparent",
|
||||
"name": "Transparent Player",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Hintergrund-Sichtbarkeit",
|
||||
@ -868,10 +897,12 @@
|
||||
"submenu": {
|
||||
"acrylic": "Acrylic",
|
||||
"mica": "Mica",
|
||||
"none": "Nichts",
|
||||
"tabbed": "Tabbed"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Transparent Player"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integration mit dem OBS-Plugin Tuna",
|
||||
|
||||
@ -813,6 +813,14 @@
|
||||
"not-found": "⚠️ No lyrics found for this song."
|
||||
},
|
||||
"menu": {
|
||||
"preferred-provider": {
|
||||
"label": "Preferred Provider",
|
||||
"tooltip": "Choose the default provider to use",
|
||||
"none": {
|
||||
"label": "None",
|
||||
"tooltip": "No preferred provider"
|
||||
}
|
||||
},
|
||||
"default-text-string": {
|
||||
"label": "Default character between lyrics",
|
||||
"tooltip": "Choose the default character to use for the gap between lyrics"
|
||||
|
||||
@ -2,14 +2,14 @@
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Error al ejecutar el plugin {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Plugin {{pluginName}}::{{contextName}} Ejecutó en {{ms}}ms",
|
||||
"initialize-failed": "Error al inicializar el plugin \"{{pluginName}}\"",
|
||||
"load-all": "Cargando todos los plugins",
|
||||
"load-failed": "Error al cargar el plugin \"{{pluginName}}\"",
|
||||
"loaded": "Plugin \"{{pluginName}}\" cargado",
|
||||
"unload-failed": "No se ha podido descargar el plugin \"{{pluginName}}\"",
|
||||
"unloaded": "Plugin \"{{pluginName}}\" descargado"
|
||||
"execute-failed": "Error al ejecutar el complemento {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Complemento {{pluginName}}::{{contextName}} Ejecutó en {{ms}}ms",
|
||||
"initialize-failed": "Error al inicializar el complemento \"{{pluginName}}\"",
|
||||
"load-all": "Cargando todos los complementos",
|
||||
"load-failed": "Error al cargar el complemento \"{{pluginName}}\"",
|
||||
"loaded": "Complementos \"{{pluginName}}\" cargado",
|
||||
"unload-failed": "No se ha podido descargar el complemento \"{{pluginName}}\"",
|
||||
"unloaded": "Complemento \"{{pluginName}}\" descargado"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -53,7 +53,7 @@
|
||||
"later": "Más tarde",
|
||||
"restart-now": "Reiniciar ahora"
|
||||
},
|
||||
"detail": "El plugin \"{{pluginName}}\" requiere reiniciar para tomar efecto",
|
||||
"detail": "El complemento \"{{pluginName}}\" requiere reiniciar para tomar efecto",
|
||||
"message": "\"{{pluginName}}\" necesita reiniciar",
|
||||
"title": "Se requiere reinicio"
|
||||
},
|
||||
@ -185,7 +185,7 @@
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Habilitado",
|
||||
"label": "Plugins",
|
||||
"label": "Complementos",
|
||||
"new": "NUEVO"
|
||||
},
|
||||
"view": {
|
||||
@ -457,7 +457,15 @@
|
||||
"hide-duration-left": "Ocultar la duración restante",
|
||||
"hide-github-button": "Ocultar el botón de enlace a GitHub",
|
||||
"play-on-youtube-music": "Reproducir en YouTube Music",
|
||||
"set-inactivity-timeout": "Establecer tiempo de inactividad"
|
||||
"set-inactivity-timeout": "Establecer tiempo de inactividad",
|
||||
"set-status-display-type": {
|
||||
"label": "Texto de estado",
|
||||
"submenu": {
|
||||
"artist": "Escuchando a {artist}",
|
||||
"title": "Escuchando {song title}",
|
||||
"youtube-music": "Escuchando YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord Rich Presence",
|
||||
"prompt": {
|
||||
@ -482,7 +490,7 @@
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "({{playlistSize}} canciones)",
|
||||
"message": "Descargando Playlist {{playlistTitle}}",
|
||||
"message": "Descargando lista de reproducción {{playlistTitle}}",
|
||||
"title": "Descarga iniciada"
|
||||
}
|
||||
},
|
||||
@ -749,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Introduzca el token de usuario de ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Usar artistas alternativos",
|
||||
"scrobble-alternative-title": "Usar títulos alternativos",
|
||||
"scrobble-other-media": "Hacer Scrobble sobre otros medios"
|
||||
},
|
||||
@ -834,6 +843,14 @@
|
||||
"label": "Haz que la letra esté perfectamente sincronizada",
|
||||
"tooltip": "Calcular al milisegundo la visualización de la siguiente línea (puede tener un pequeño impacto en el rendimiento)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Proveedor preferido",
|
||||
"none": {
|
||||
"label": "Ninguno",
|
||||
"tooltip": "Ningún proveedor preferido"
|
||||
},
|
||||
"tooltip": "Elige el proveedor predeterminado que deseas usar"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Romanizar letras",
|
||||
"tooltip": "Si la letra está en un idioma diferente, intenta mostrar una versión en latín."
|
||||
@ -866,8 +883,29 @@
|
||||
"description": "Añade un widget TouchBar para los usuarios de macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Hace que la ventana de la aplicación sea transparente",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Opacidad",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Tipo",
|
||||
"submenu": {
|
||||
"acrylic": "Acrílico",
|
||||
"mica": "Mica",
|
||||
"none": "Ninguno",
|
||||
"tabbed": "Con pestañas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Reproductor transparente"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integración con el plugin Tuna de OBS",
|
||||
"description": "Integración con el complemento Tuna de OBS",
|
||||
"name": "Tuna OBS"
|
||||
},
|
||||
"unobtrusive-player": {
|
||||
|
||||
@ -150,6 +150,13 @@
|
||||
"visual-tweaks": {
|
||||
"label": "Mga Biswal na Tweak",
|
||||
"submenu": {
|
||||
"custom-window-title": {
|
||||
"label": "Custom na window title",
|
||||
"prompt": {
|
||||
"label": "I-enter ang custom na window tile: (iwanang blanko para ma-disable)",
|
||||
"placeholder": "Halimbawa: YouTube Music"
|
||||
}
|
||||
},
|
||||
"like-buttons": {
|
||||
"default": "Default",
|
||||
"force-show": "Pilitang ipakita",
|
||||
@ -378,6 +385,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "I-configure ang custom na output media device para sa mga kanta",
|
||||
"menu": {
|
||||
"device-selector": "Pumili ng Device"
|
||||
},
|
||||
"name": "Custom na Output Device",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Pumili ng output media device na gagamitin",
|
||||
"title": "Pumili ng Output Device"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Gawing simulan ang kanta sa \"naka-pause\" na mode",
|
||||
"menu": {
|
||||
@ -401,7 +421,14 @@
|
||||
"hide-duration-left": "Itago ang natitirang oras",
|
||||
"hide-github-button": "Itago ang button na GitHub link",
|
||||
"play-on-youtube-music": "Patugtugin sa YouTube Music",
|
||||
"set-inactivity-timeout": "I-set ang inactivity timeout"
|
||||
"set-inactivity-timeout": "I-set ang inactivity timeout",
|
||||
"set-status-display-type": {
|
||||
"submenu": {
|
||||
"artist": "Nakikinig sa {artist}",
|
||||
"title": "Nakikinig sa {song title}",
|
||||
"youtube-music": "Kumikinig sa YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
@ -649,6 +676,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Ilagay ang user token ng ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Gumamit ng mga alternatibong artist",
|
||||
"scrobble-alternative-title": "Gumamit ng alternatibong mga title",
|
||||
"scrobble-other-media": "Mag-Scrobble ng ibang media"
|
||||
},
|
||||
@ -728,6 +756,14 @@
|
||||
"label": "Gawing perpektong naka-sync ang lyrics",
|
||||
"tooltip": "Kalkulahin sa millisecond ang pagpapakita ng susunod na linya (maaaring magkaroon ng maliit na epekto sa performance)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Napiling Provider",
|
||||
"none": {
|
||||
"label": "Wala",
|
||||
"tooltip": "Walang napiling provider"
|
||||
},
|
||||
"tooltip": "Pumili ng default na provider para gagamitin"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "I-romanize ang lyrics",
|
||||
"tooltip": "Kung ang lyrics ay nasa ibang wika, subukang magpakita ng latin na bersyon."
|
||||
@ -758,6 +794,19 @@
|
||||
"touchbar": {
|
||||
"description": "Idaragdag ang TouchBar na widget para sa mga user ng macOS"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Gawing transparent ang app window",
|
||||
"menu": {
|
||||
"type": {
|
||||
"label": "Uri",
|
||||
"submenu": {
|
||||
"none": "Wala",
|
||||
"tabbed": "Naka-tab"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Transparent na Player"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integrasyon kasama ang Tuna na OBS plugin"
|
||||
},
|
||||
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "Configurer un périphérique de sortie personnalisé pour les morceaux",
|
||||
"menu": {
|
||||
"device-selector": "Sélectionner un appareil"
|
||||
},
|
||||
"name": "Périphérique de sortie personnalisé",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Choisissez le périphérique de sortie à utiliser",
|
||||
"title": "Sélectionner le périphérique de sortie"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Fait démarrer la chanson en mode \"pause\"",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "Masquer la durée restante",
|
||||
"hide-github-button": "Masquer le bouton du lien GitHub",
|
||||
"play-on-youtube-music": "Jouer sur YouTube Music",
|
||||
"set-inactivity-timeout": "Définir le délai d'inactivité"
|
||||
"set-inactivity-timeout": "Définir le délai d'inactivité",
|
||||
"set-status-display-type": {
|
||||
"label": "Texte d'état",
|
||||
"submenu": {
|
||||
"artist": "Écoute {artiste}",
|
||||
"title": "Écoute {titre de la chanson}",
|
||||
"youtube-music": "Écoute YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord Rich Presence",
|
||||
"prompt": {
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Entrer le token utilisateur de ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Utilisez d'autres artistes",
|
||||
"scrobble-alternative-title": "Utiliser des titres alternatifs",
|
||||
"scrobble-other-media": "Scrobbler d'autres médias"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "Rend les paroles parfaitement synchronisées",
|
||||
"tooltip": "Calcul à la milliseconde près l'affichage de la ligne suivante (peut avoir un faible impact sur les performances)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Fournisseur privilégié",
|
||||
"none": {
|
||||
"label": "Aucun",
|
||||
"tooltip": "Aucun fournisseur privilégié"
|
||||
},
|
||||
"tooltip": "Choisissez le fournisseur par défaut à utiliser"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Romaniser les paroles",
|
||||
"tooltip": "Si les paroles sont dans une autre langue, essayez de les afficher dans une version latine."
|
||||
@ -853,6 +883,27 @@
|
||||
"description": "Ajoute un widget TouchBar pour les utilisateurs de macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Rend la fenêtre de l'application transparente",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Opacité",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Type",
|
||||
"submenu": {
|
||||
"acrylic": "Acrylique",
|
||||
"mica": "Mica",
|
||||
"none": "Aucun",
|
||||
"tabbed": "À onglets"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Lecteur transparent"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Intégration avec le plugin OBS Tuna",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -150,6 +150,13 @@
|
||||
"visual-tweaks": {
|
||||
"label": "Penyesuaian Visual",
|
||||
"submenu": {
|
||||
"custom-window-title": {
|
||||
"label": "Judul jendela kustom",
|
||||
"prompt": {
|
||||
"label": "Masukkan judul jendela kustom (kosongkan untuk menonaktifkan)",
|
||||
"placeholder": "Contoh: YouTube Music"
|
||||
}
|
||||
},
|
||||
"like-buttons": {
|
||||
"default": "Standar",
|
||||
"force-show": "Pertunjukan paksa",
|
||||
@ -414,6 +421,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"menu": {
|
||||
"device-selector": "Pilih Perangkat"
|
||||
},
|
||||
"name": "Perangkat Keluaran Kustom",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Pilih perangkat media keluaran yang akan digunakan",
|
||||
"title": "Pilih Perangkat Keluaran"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Buat lagu mulai dalam mode \"jeda\"",
|
||||
"menu": {
|
||||
@ -437,7 +456,15 @@
|
||||
"hide-duration-left": "Sembunyikan sisa durasi",
|
||||
"hide-github-button": "Sembunyikan tombol link GitHub",
|
||||
"play-on-youtube-music": "Mainkan di YouTube Music",
|
||||
"set-inactivity-timeout": "Tetapkan batas waktu tidak aktif"
|
||||
"set-inactivity-timeout": "Tetapkan batas waktu tidak aktif",
|
||||
"set-status-display-type": {
|
||||
"label": "Teks status",
|
||||
"submenu": {
|
||||
"artist": "Sedang mendengarkan {artist}",
|
||||
"title": "Sedang mendengarkan {song title}",
|
||||
"youtube-music": "Sedang mendengarkan YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Rich Presence Discord",
|
||||
"prompt": {
|
||||
@ -454,16 +481,16 @@
|
||||
"buttons": {
|
||||
"ok": "Oke"
|
||||
},
|
||||
"message": "Argh! Maaf, dowloadnya gagal…",
|
||||
"title": "Downloadnya error!"
|
||||
"message": "Argh! Maaf, dowload gagal…",
|
||||
"title": "Terjadi kesalahan dalam unduhan!"
|
||||
},
|
||||
"start-download-playlist": {
|
||||
"buttons": {
|
||||
"ok": "Oke"
|
||||
},
|
||||
"detail": "({{playlistSize}} lagu-lagu)",
|
||||
"message": "Mengunduh Playlist {{playlistTitle}}",
|
||||
"title": "Download dimulai"
|
||||
"message": "Mengunduh Daftar Putar {{playlistTitle}}",
|
||||
"title": "Pengunduhan dimulai"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
@ -474,8 +501,8 @@
|
||||
"download-progress": "Mengunduh: {{percent}}%",
|
||||
"downloading": "Mengunduh…",
|
||||
"downloading-counter": "Mengunduh {{current}}/{{total}}…",
|
||||
"downloading-playlist": "Mengunduh playlist \"{{playlistTitle}}\" - {{playlistSize}} lagu ({{playlistId}})",
|
||||
"error-while-downloading": "Gagal mengunduh \"{{author}} - {{title}}\": {{error}}",
|
||||
"downloading-playlist": "Mengunduh Daftar Putar \"{{playlistTitle}}\" - {{playlistSize}} lagu-lagu ({{playlistId}})",
|
||||
"error-while-downloading": "Gagal dalam mengunduh \"{{author}} - {{title}}\": {{error}}",
|
||||
"folder-already-exists": "Folder {{playlistFolder}} sudah ada",
|
||||
"getting-playlist-info": "Mendapatkan informasi playlist…",
|
||||
"loading": "Memuat…",
|
||||
@ -530,7 +557,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Equalizer"
|
||||
"name": "Ekualiser"
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "Buat penggeser volume menjadi eksponen sehingga memudahkan memilih volume yang lebih rendah.",
|
||||
|
||||
@ -150,6 +150,13 @@
|
||||
"visual-tweaks": {
|
||||
"label": "Miglioramenti visivi",
|
||||
"submenu": {
|
||||
"custom-window-title": {
|
||||
"label": "Personalizza titolo finestra",
|
||||
"prompt": {
|
||||
"label": "Inserisci un titolo della finestra personalizzato: (lascia vuoto per disattivare)",
|
||||
"placeholder": "Esempio: YouTube Music"
|
||||
}
|
||||
},
|
||||
"like-buttons": {
|
||||
"default": "Predefinito",
|
||||
"force-show": "Forza la visualizzazione",
|
||||
@ -414,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "Scegli da quale uscita audio vuoi riprodurre i brani",
|
||||
"menu": {
|
||||
"device-selector": "Seleziona un'uscita"
|
||||
},
|
||||
"name": "Dispositivo di Output Personalizzato",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Scegli il dispositivo d'output da utilizzare",
|
||||
"title": "Scegli il dispositivo d'output"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Fa iniziare i brani in modalità \"pausa\"",
|
||||
"menu": {
|
||||
@ -437,7 +457,15 @@
|
||||
"hide-duration-left": "Nascondi la durata rimasta",
|
||||
"hide-github-button": "Nascondi il pulsante link a GitHub",
|
||||
"play-on-youtube-music": "Riproduci su YouTube Music",
|
||||
"set-inactivity-timeout": "Imposta il timeout di inattività"
|
||||
"set-inactivity-timeout": "Imposta il timeout di inattività",
|
||||
"set-status-display-type": {
|
||||
"label": "Testo dello status",
|
||||
"submenu": {
|
||||
"artist": "Stai ascoltando {artist}",
|
||||
"title": "Stai ascoltando {song title}",
|
||||
"youtube-music": "Ascoltando YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord Rich Presence",
|
||||
"prompt": {
|
||||
@ -729,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Inserire il token utente per ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Usa artisti alternativi",
|
||||
"scrobble-alternative-title": "Usa titoli alternativi",
|
||||
"scrobble-other-media": "Scrobble altri media"
|
||||
},
|
||||
@ -814,6 +843,14 @@
|
||||
"label": "Rendi i testi perfettamente sincronizzati",
|
||||
"tooltip": "Calcola al millisecondo la visualizzazione della riga successiva (può avere un piccolo impatto sulle prestazioni)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Provider preferito",
|
||||
"none": {
|
||||
"label": "Nessuno",
|
||||
"tooltip": "Nessun provider preferito"
|
||||
},
|
||||
"tooltip": "Scegli quale provider predefinito utilizzare"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Testi in caratteri occidentali",
|
||||
"tooltip": "Qualora il testo fosse scritto in una lingua non occidentale, prova a visualizzarlo in caratteri latini."
|
||||
@ -846,6 +883,27 @@
|
||||
"description": "Aggiunge un widget TouchBar per gli utenti macOS",
|
||||
"name": "Touch Bar (per MacOS)"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Rende trasparente la finestra del programma",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Opacità",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Tipo",
|
||||
"submenu": {
|
||||
"acrylic": "Acrilico",
|
||||
"mica": "Mica",
|
||||
"none": "Nessuno",
|
||||
"tabbed": "In scheda"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Player Trasparente"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integrazione con il plugin OBS Tuna",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "미디어 출력 장치 구성",
|
||||
"menu": {
|
||||
"device-selector": "장치 선택"
|
||||
},
|
||||
"name": "출력 장치 커스텀",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "사용할 미디어 출력 장치를 선택하세요",
|
||||
"title": "출력 장치 선택"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "노래를 '일시 정지' 모드로 시작하게 합니다",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "남은 재생 시간 숨기기",
|
||||
"hide-github-button": "GitHub 링크 버튼 숨기기",
|
||||
"play-on-youtube-music": "유튜브 뮤직에서 재생",
|
||||
"set-inactivity-timeout": "비활성 시간 제한 설정"
|
||||
"set-inactivity-timeout": "비활성 시간 제한 설정",
|
||||
"set-status-display-type": {
|
||||
"label": "상태 텍스트",
|
||||
"submenu": {
|
||||
"artist": "{아티스트} 듣는 중",
|
||||
"title": "{곡 제목} 듣는 중",
|
||||
"youtube-music": "YouTube Music 듣는 중"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "디스코드 활동 상태",
|
||||
"prompt": {
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "ListenBrainz 유저 토큰 입력"
|
||||
},
|
||||
"scrobble-alternative-artist": "대체 아티스트 명 사용",
|
||||
"scrobble-alternative-title": "대체 제목 사용하기",
|
||||
"scrobble-other-media": "다른 미디어 스크로블하기"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "가사를 최대한 정교하게 동기화",
|
||||
"tooltip": "다음 줄의 표시를 밀리초 단위로 계산합니다 (성능에 약간의 영향을 미칠 수 있음)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "선호하는 가사 제공자",
|
||||
"none": {
|
||||
"label": "없음",
|
||||
"tooltip": "선호하는 가사 제공자 없음"
|
||||
},
|
||||
"tooltip": "사용할 기본 가사 제공자를 선택하세요"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "가사 로마자 변환",
|
||||
"tooltip": "가사가 영어가 아닌 언어로 되어있는 경우, 로마자 표기를 표시합니다."
|
||||
@ -853,6 +883,27 @@
|
||||
"description": "macOS 사용자를 위한 TouchBar 위젯을 추가합니다",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "애플리케이션 창을 투명하게 만듭니다",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "불투명도",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "종류",
|
||||
"submenu": {
|
||||
"acrylic": "아크릴",
|
||||
"mica": "미카",
|
||||
"none": "없음",
|
||||
"tabbed": "탭"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "투명 플레이어"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "OBS의 확장인 Tuna와의 통합을 활성화합니다",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -59,6 +59,7 @@
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "ഉപേക്ഷിക്കുക",
|
||||
"relaunch": "പുനരാരംഭിക്കുക",
|
||||
"wait": "കാത്തിരിക്കൂ"
|
||||
},
|
||||
@ -109,5 +110,22 @@
|
||||
"enabled": "പ്രവർത്തനക്ഷമമാക്കി"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"video-toggle": {
|
||||
"menu": {
|
||||
"align": {
|
||||
"label": "ക്രമപ്പെടുത്തൽ",
|
||||
"submenu": {
|
||||
"left": "ഇടത്",
|
||||
"middle": "മധ്യഭാഗം",
|
||||
"right": "വലത്"
|
||||
}
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"button-video": "വീഡിയോ"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -821,6 +821,11 @@
|
||||
"label": "Zorg ervoor dat de songteksten perfect gesynchroniseerd zijn",
|
||||
"tooltip": "Bereken tot op de milliseconde de weergave van de volgende regel (kan een kleine impact hebben op de prestaties)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"none": {
|
||||
"tooltip": "Geen provider beschikbaar"
|
||||
}
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Romaniseer songtekst",
|
||||
"tooltip": "Als de songtekst in een andere taal is, probeer dan een Latijnse versie weer te geven."
|
||||
|
||||
@ -757,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Insira o token de usuário ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Use artistas alternativos",
|
||||
"scrobble-alternative-title": "Usar títulos alternativos",
|
||||
"scrobble-other-media": "Scrobble outras mídias"
|
||||
},
|
||||
@ -842,6 +843,14 @@
|
||||
"label": "Deixa as letras perfeitamente sincronizadas",
|
||||
"tooltip": "Calcular até o milissegundo a exibição da próxima linha (pode ter um pequeno impacto no desempenho)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Provedor Preferido",
|
||||
"none": {
|
||||
"label": "Nenhum",
|
||||
"tooltip": "Sem provedor preferido"
|
||||
},
|
||||
"tooltip": "Escolha o provedor padrão para uso"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Letras romanizadas",
|
||||
"tooltip": "Se as letras estiverem em um idioma diferente, tente exibir uma versão latina."
|
||||
@ -874,6 +883,27 @@
|
||||
"description": "Adiciona um widget TouchBar para usuários do macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Faz a janela do app transparente",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Opacidade",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Tipo",
|
||||
"submenu": {
|
||||
"acrylic": "Acrílico",
|
||||
"mica": "Mica",
|
||||
"none": "Nenhum",
|
||||
"tabbed": "Em abas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Player transparente"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integração com o plugin Tuna do OBS",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -136,13 +136,13 @@
|
||||
"start-at-login": "Iniciar com o sistema",
|
||||
"starting-page": {
|
||||
"label": "Página inicial",
|
||||
"unset": "Limpar"
|
||||
"unset": "Indefinida"
|
||||
},
|
||||
"tray": {
|
||||
"label": "Área de notificação",
|
||||
"submenu": {
|
||||
"disabled": "Desativada",
|
||||
"enabled-and-hide-app": "Ativado e ocultar aplicação",
|
||||
"enabled-and-hide-app": "Ativada e ocultar aplicação",
|
||||
"enabled-and-show-app": "Ativada e a mostrar aplicação",
|
||||
"play-pause-on-click": "Reprodução/Pausa ao clicar"
|
||||
}
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "Configurar um dispositivo de saída padrão para as músicas",
|
||||
"menu": {
|
||||
"device-selector": "Selecionar dispositivo"
|
||||
},
|
||||
"name": "Dispositivo personalizado",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Escolha o dispositivo de saída a utilizar",
|
||||
"title": "Selecione o dispositivo de saída"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Faz com que a música inicie no modo \"pausa\"",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "Ocultar tempo restante",
|
||||
"hide-github-button": "Ocultar botão GitHub",
|
||||
"play-on-youtube-music": "Reproduzir em YouTube Music",
|
||||
"set-inactivity-timeout": "Definir tempo de inatividade"
|
||||
"set-inactivity-timeout": "Definir tempo de inatividade",
|
||||
"set-status-display-type": {
|
||||
"label": "Texto de estado",
|
||||
"submenu": {
|
||||
"artist": "A ouvir {artist}",
|
||||
"title": "A ouvir {song title}",
|
||||
"youtube-music": "A reproduzir YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord Rich Presence",
|
||||
"prompt": {
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Introduza o 'token' do utilizador ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Utilizar artistas alternativos",
|
||||
"scrobble-alternative-title": "Utilizar títulos alternativos",
|
||||
"scrobble-other-media": "Scrobble de outros conteúdos"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "Sincronização perfeita da entre letra e música",
|
||||
"tooltip": "Calcular, ao milissegundo, a exibição da linha seguinte (pode ter um pequeno impacto no desempenho)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Serviço preferencial",
|
||||
"none": {
|
||||
"label": "Nenhum",
|
||||
"tooltip": "Nenhum serviço preferencial"
|
||||
},
|
||||
"tooltip": "Escolha o serviço padrão a utilizar"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Letras romanas",
|
||||
"tooltip": "Se as letras estiverem num idioma diferente, tentar mostrar uma versão em latim"
|
||||
@ -853,6 +883,27 @@
|
||||
"description": "Adicionar widget TouchBar para utilizadores macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Tornar janela da aplicação transparente",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Opacidade",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Tipo",
|
||||
"submenu": {
|
||||
"acrylic": "Acrílico",
|
||||
"mica": "Mica",
|
||||
"none": "Nada",
|
||||
"tabbed": "Separadores"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Reprodutor transparente"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integração com o plugin Tuna do OBS",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -757,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Введите токен пользователя ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Использовать альтернативных исполнителей",
|
||||
"scrobble-alternative-title": "Использовать альтернативные названия",
|
||||
"scrobble-other-media": "Скробблинг других медиа"
|
||||
},
|
||||
@ -842,6 +843,14 @@
|
||||
"label": "Идеально синхронизировать слова",
|
||||
"tooltip": "До миллисекунды рассчитывает отображение следующей строки(может оказать небольшое влияние на производительность)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Предпочитаемый источник",
|
||||
"none": {
|
||||
"label": "Никакой",
|
||||
"tooltip": "Нет предпочитаемого источника"
|
||||
},
|
||||
"tooltip": "Выберите источник по умолчанию"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Романизировать слова",
|
||||
"tooltip": "Если слова на другом языке, пытаться отображать версию на латинице."
|
||||
@ -874,6 +883,27 @@
|
||||
"description": "Добавляет виджет тачбара для пользователей macOS",
|
||||
"name": "Тачбар"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Делает окно приложения прозрачным",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Непрозрачность",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Тип",
|
||||
"submenu": {
|
||||
"acrylic": "Acrylic",
|
||||
"mica": "Mica",
|
||||
"none": "Отключено",
|
||||
"tabbed": "Tabbed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Прозрачный плеер"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Интеграция с плагином Tuna от OBS",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "Konfigurišite prilagođeni izlazni medijski uređaj za pesme",
|
||||
"menu": {
|
||||
"device-selector": "Izaberite uređaj"
|
||||
},
|
||||
"name": "Prilagođeni izlazni uređaj",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Izaberite izlazni medijski uređaj koji će se koristiti",
|
||||
"title": "Izaberite izlazni uređaj"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Numere se pokreću u pauziranom režimu",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "Sakrij preostalo vreme",
|
||||
"hide-github-button": "Sakrij dugme sa GitHub linkom",
|
||||
"play-on-youtube-music": "Reprodukuj na YouTube Muzici",
|
||||
"set-inactivity-timeout": "Podesi tajmer za neaktivnost"
|
||||
"set-inactivity-timeout": "Podesi tajmer za neaktivnost",
|
||||
"set-status-display-type": {
|
||||
"label": "Tekst statusa",
|
||||
"submenu": {
|
||||
"artist": "Slušanje {artist}",
|
||||
"title": "Slušanje {song title}",
|
||||
"youtube-music": "Slušanje YouTube muzike"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord Bogato Prisustvo",
|
||||
"prompt": {
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Unesi korisnički žeton za ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Koristi alternativne izvođače",
|
||||
"scrobble-alternative-title": "Koristi alternativne naslove",
|
||||
"scrobble-other-media": "Učetkaj druge medije"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "Učini da tekst pesme bude savršeno usklađen",
|
||||
"tooltip": "Izračunaj do milisekunde prikaz sledeće linije teksta (može malo uticati na učinak)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Preferirani dobavljač",
|
||||
"none": {
|
||||
"label": "Nijedan",
|
||||
"tooltip": "Bez preferiranog dobavljača"
|
||||
},
|
||||
"tooltip": "Izaberite podrazumevanog dobavljača kog ćete koristiti"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Romanizuj tekstove pesama",
|
||||
"tooltip": "Ako je tekst pesme na drugom jeziku, pokušaj da ga prikažeš u latiničnoj varijanti."
|
||||
@ -853,6 +883,27 @@
|
||||
"description": "Dodaje dodatak dodirne trake za macOS korisnike",
|
||||
"name": "Dodirna Traka"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Čini prozor aplikacije transparentnim",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Neprozirnost",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Tip",
|
||||
"submenu": {
|
||||
"acrylic": "Akrilan",
|
||||
"mica": "Mika",
|
||||
"none": "Nijedan",
|
||||
"tabbed": "Kartice"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Transparentni plejer"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integracija sa OBS-ovim Tuna dodatkom",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -86,7 +86,7 @@
|
||||
"copy-current-url": "Kopiera nuvarande länk",
|
||||
"go-back": "Gå tillbaka",
|
||||
"go-forward": "Gå framåt",
|
||||
"quit": "Lämna",
|
||||
"quit": "Avsluta",
|
||||
"restart": "Starta om appen"
|
||||
}
|
||||
},
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "Konfigurera en anpassad utdataenhet för låtar",
|
||||
"menu": {
|
||||
"device-selector": "Välj enhet"
|
||||
},
|
||||
"name": "Anpassad Utdataenhet",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Välj den utdataenhet som ska användas",
|
||||
"title": "Välj utdataenhet"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Starta låt i \"pausat\" läge",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "Dölj återstående tid",
|
||||
"hide-github-button": "Dölj knapp för GitHub-länk",
|
||||
"play-on-youtube-music": "Spela på YouTube Music",
|
||||
"set-inactivity-timeout": "Ställ in inaktivitetstid"
|
||||
"set-inactivity-timeout": "Ställ in inaktivitetstid",
|
||||
"set-status-display-type": {
|
||||
"label": "Statusmeddelande",
|
||||
"submenu": {
|
||||
"artist": "Lyssnar på {artist}",
|
||||
"title": "Lyssnar på {song title}",
|
||||
"youtube-music": "Lyssnar på YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord Aktivitetsdelning",
|
||||
"prompt": {
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Ange ListenBrainz användartoken"
|
||||
},
|
||||
"scrobble-alternative-artist": "Använd alternativa artister",
|
||||
"scrobble-alternative-title": "Använd alternativa titlar",
|
||||
"scrobble-other-media": "Scrobbla annan media"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "Gör låttexterna perfekt synkroniserade",
|
||||
"tooltip": "Beräkna till millisekunden när nästa rad ska visas (kan ha en liten inverkan på prestanda)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Föredragen leverantör",
|
||||
"none": {
|
||||
"label": "Ingen",
|
||||
"tooltip": "Ingen föredragen leverantör"
|
||||
},
|
||||
"tooltip": "Välj standardleverantör att använda"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Romanisera låttexter",
|
||||
"tooltip": "Om låttexterna är på ett annat språk, försök visa en latinsk version."
|
||||
@ -853,6 +883,27 @@
|
||||
"description": "Lägger till en TouchBar-widget för macOS-användare",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Gör appfönstret genomskinligt",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Opacitet",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Typ",
|
||||
"submenu": {
|
||||
"acrylic": "Akryl",
|
||||
"mica": "Mica",
|
||||
"none": "Ingen",
|
||||
"tabbed": "Flikad"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Genomskinlig Spelare"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integration med OBS-pluginprogrammet Tuna",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "ตั้งค่าอุปกรณ์เสียงออกสำหรับเพลง",
|
||||
"menu": {
|
||||
"device-selector": "เลือกอุปกรณ์"
|
||||
},
|
||||
"name": "อุปกรณ์เสียงออกที่กำหนดเอง",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "เลือกอุปกรณ์เสียงออกที่ต้องการใช้",
|
||||
"title": "เลือกอุปกรณ์เสียงออก"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "เริ่มเพลงในโหมดหยุดชั่วคราว",
|
||||
"menu": {
|
||||
@ -744,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "ใส่ user token ของ ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "ใช้ชื่อศิลปินอื่น",
|
||||
"scrobble-alternative-title": "ใช้ชื่ออื่น",
|
||||
"scrobble-other-media": "บันทึกการเล่นสื่ออื่นๆ"
|
||||
},
|
||||
@ -829,6 +843,14 @@
|
||||
"label": "ให้เนื้อเพลงตรงกับเพลงเป๊ะๆ",
|
||||
"tooltip": "คำนวณมิลิวินาทีในการแสดงบรรทัดถัดไป (มีผลเล็กน้อยกับประสิทธิภาพการทำงาน)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "ผู้ให้บริการที่ต้องการ",
|
||||
"none": {
|
||||
"label": "ไม่มี",
|
||||
"tooltip": "ไม่มีผู้ให้บริการที่ต้องการ"
|
||||
},
|
||||
"tooltip": "เลือกผู้ให้บริการที่ต้องการใช้งาน"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "เนื้อเพลงตัวด้วยอักษรโรมัน",
|
||||
"tooltip": "ถ้าหากเนื้อเพลงอยู่ในภาษาอื่น ลองเปลี่ยนการแสดงผลโดยใช้เวอร์ชั่นลาติน"
|
||||
@ -861,6 +883,27 @@
|
||||
"description": "เพิ่ม Widget บน TouchBar สำหรับผู้ใช้ macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "ทำให้หน้าต่างของแอปโปร่งใส",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "ความทึบแสง",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "ประเภท",
|
||||
"submenu": {
|
||||
"acrylic": "อะคริลิก",
|
||||
"mica": "ไมกา",
|
||||
"none": "ไม่มี",
|
||||
"tabbed": "Tabbed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "ที่เล่นเพลงโปร่งใส"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "ใช้งานร่วมกันกับปลั้กอิน Tuna บน OBS",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "Şarkılar için özel bir medya çıkış aygıtı ayarlayın",
|
||||
"menu": {
|
||||
"device-selector": "Aygıt Seçin"
|
||||
},
|
||||
"name": "Özel Çıkış Aygıtı",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Kullanılacak medya çıkış aygıtını seçin",
|
||||
"title": "Çıkış Aygıtını Seçin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Şarkıların otomatik olarak duraklatılmasını sağlar",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "Kalan süreyi gizle",
|
||||
"hide-github-button": "GitHub bağlantısını gizle",
|
||||
"play-on-youtube-music": "YouTube Music de oynat",
|
||||
"set-inactivity-timeout": "Hareketsizlik zaman aşımını ayarla"
|
||||
"set-inactivity-timeout": "Hareketsizlik zaman aşımını ayarla",
|
||||
"set-status-display-type": {
|
||||
"label": "Durum metni",
|
||||
"submenu": {
|
||||
"artist": "{artist} Dinleniyor",
|
||||
"title": "{song title} Dinleniyor",
|
||||
"youtube-music": "YouTube Müzik Dinleniyor"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord Etkinlik Durumu",
|
||||
"prompt": {
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "ListenBrainz kullanıcı kimliğinizi girin"
|
||||
},
|
||||
"scrobble-alternative-artist": "Alternatif sanatçıları kullan",
|
||||
"scrobble-alternative-title": "Alternatif başlıklar kullan",
|
||||
"scrobble-other-media": "Diğer medya ortamlarında listele"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "Şarkı sözlerini mükemmel şekilde senkronize edin",
|
||||
"tooltip": "Bir sonraki satırın görüntülenmesini milisaniyesine kadar hesaplayın (performans üzerinde küçük bir etkisi olabilir)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Tercih edilen Sağlayıcı",
|
||||
"none": {
|
||||
"label": "Hiçbiri",
|
||||
"tooltip": "Varsayılan sağlayıcı yok"
|
||||
},
|
||||
"tooltip": "Kullanmak İçin varsayılan sağlayıcıyı seçin"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Sözleri Romanize Et",
|
||||
"tooltip": "Sözler başka bir dilde gözüküyorsa, Latin versiyonunu dene."
|
||||
@ -853,6 +883,27 @@
|
||||
"description": "macOS kullanıcıları için bir TouchBar widget'ı ekler",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Uygulama penceresini şeffaf yapar",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Opaklık",
|
||||
"submenu": {
|
||||
"percent": "%{{opacity}}"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Tür",
|
||||
"submenu": {
|
||||
"acrylic": "Akrilik",
|
||||
"mica": "Mika",
|
||||
"none": "Hiçbiri",
|
||||
"tabbed": "Sekmeli"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Şeffaf Oynatıcı"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "OBS eklentisi Tuna ile entegrasyon sağlar",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "Cài đặt cho thiết bị đầu ra tùy chỉnh cho bài hát",
|
||||
"menu": {
|
||||
"device-selector": "Chọn thiết bị"
|
||||
},
|
||||
"name": "Thiết bị đầu ra tùy chỉnh",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "Chọn thiết bị phát làm đầu ra để dùng",
|
||||
"title": "Chọn thiết bị đầu ra"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Làm nhạc bắt đầu ở chế độ \"tạm dừng\". Ngoài ra có thể dừng nhạc khi khởi động ứng dụng (nếu có bật tính năng \"Tiếp tục bài hát cuối cùng khi ứng dụng khởi động\")",
|
||||
"menu": {
|
||||
@ -444,9 +457,17 @@
|
||||
"hide-duration-left": "Ẩn thời lượng còn lại",
|
||||
"hide-github-button": "Ẩn nút liên kết GitHub",
|
||||
"play-on-youtube-music": "Phát trong Youtube Music",
|
||||
"set-inactivity-timeout": "Đặt thời gian chờ không hoạt động"
|
||||
"set-inactivity-timeout": "Đặt thời gian chờ không hoạt động",
|
||||
"set-status-display-type": {
|
||||
"label": "Văn bản trạng thái",
|
||||
"submenu": {
|
||||
"artist": "Đang nghe nhạc của {artist}",
|
||||
"title": "Đang nghe nhạc {song title}",
|
||||
"youtube-music": "Đang nghe Youtube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord Rich Presence",
|
||||
"name": "Tích hợp trạng thái Discord",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "Nhập thời gian chờ không hoạt động tính bằng giây:",
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "Nhập mã người dùng ListenBrainz"
|
||||
},
|
||||
"scrobble-alternative-artist": "Dùng nghệ sĩ thay thế",
|
||||
"scrobble-alternative-title": "Dùng tiêu đề thay thế",
|
||||
"scrobble-other-media": "Scrobber nội dung khác"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "Làm cho lời bài hát được đồng bộ hoàn hảo",
|
||||
"tooltip": "Tính toán chính xác đến mili giây thời gian hiển thị dòng tiếp theo (có thể có tác động nhỏ đến hiệu suất)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "Nhà cung cấp ưa thích",
|
||||
"none": {
|
||||
"label": "Không có",
|
||||
"tooltip": "Không có nhà cung cấp ưu thích"
|
||||
},
|
||||
"tooltip": "Chọn nhà cung cấp lời bài hát mặc định để sử dụng"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "Chuyển lời bài hát sang chữ Latin",
|
||||
"tooltip": "Nếu lời bài hát đang ở ngôn ngữ khác, thử hiển thị phiên bản bảng chữ cái La-tinh."
|
||||
@ -853,6 +883,27 @@
|
||||
"description": "Thêm tiện ích TouchBar cho người dùng macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "Làm cho cửa sổ ứng dụng có hiệu ứng trong suốt",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "Độ mờ",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "Kiểu nền",
|
||||
"submenu": {
|
||||
"acrylic": "Acrylic",
|
||||
"mica": "Mica",
|
||||
"none": "Không có",
|
||||
"tabbed": "Tabbed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Trình phát trong suốt"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Tích hợp với plugin Tuna của OBS",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "配置歌曲的自定义输出媒体设备",
|
||||
"menu": {
|
||||
"device-selector": "选择设备"
|
||||
},
|
||||
"name": "自定义输出设备",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "选择要使用的输出媒体设备",
|
||||
"title": "选择输出设备"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "让曲目开始时处于 “暂停” 模式",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "隐藏剩余时长",
|
||||
"hide-github-button": "隐藏 GitHub 链接按钮",
|
||||
"play-on-youtube-music": "转至 YouTube Music 播放",
|
||||
"set-inactivity-timeout": "设置非活跃时长"
|
||||
"set-inactivity-timeout": "设置非活跃时长",
|
||||
"set-status-display-type": {
|
||||
"label": "状态文本",
|
||||
"submenu": {
|
||||
"artist": "在听 {artist}",
|
||||
"title": "在听 {song title}",
|
||||
"youtube-music": "在听 YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord Rich Presence 状态显示",
|
||||
"prompt": {
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "输入 ListenBrainz 用户令牌"
|
||||
},
|
||||
"scrobble-alternative-artist": "使用替代艺术家",
|
||||
"scrobble-alternative-title": "使用替代标题",
|
||||
"scrobble-other-media": "记录其他媒体文件"
|
||||
},
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "让滚动歌词完全同步",
|
||||
"tooltip": "以毫秒精度估算下句歌词的显示时间(可能对性能有小幅影响)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "首选歌词源",
|
||||
"none": {
|
||||
"label": "无",
|
||||
"tooltip": "没有首选的歌词源"
|
||||
},
|
||||
"tooltip": "选择默认要用的源"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "将歌词罗马化",
|
||||
"tooltip": "如果歌词以不同语言显示,试着展示拉丁字母版本。"
|
||||
@ -853,6 +883,27 @@
|
||||
"description": "为 macOS 用户启用 TouchBar 支持",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "把应用窗口变透明",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "不透明",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "类型",
|
||||
"submenu": {
|
||||
"acrylic": "亚克力",
|
||||
"mica": "云母",
|
||||
"none": "无",
|
||||
"tabbed": "标签"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "透明播放器"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "与 OBS 的 Tuna 插件集成",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -151,9 +151,9 @@
|
||||
"label": "介面設定",
|
||||
"submenu": {
|
||||
"custom-window-title": {
|
||||
"label": "客制化窗口標題",
|
||||
"label": "客製化窗口標題",
|
||||
"prompt": {
|
||||
"label": "輸入客制化窗口標題: (留空讓其禁用)",
|
||||
"label": "輸入客製化窗口標題: (留空讓其停用)",
|
||||
"placeholder": "例如: YouTube 音樂"
|
||||
}
|
||||
},
|
||||
@ -421,6 +421,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom-output-device": {
|
||||
"description": "為歌曲設定自訂輸出媒體裝置",
|
||||
"menu": {
|
||||
"device-selector": "選擇裝置"
|
||||
},
|
||||
"name": "自訂輸出裝置",
|
||||
"prompt": {
|
||||
"device-selector": {
|
||||
"label": "選擇要使用的輸出媒體裝置",
|
||||
"title": "選擇輸出裝置"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "讓歌曲開始時為暫停模式",
|
||||
"menu": {
|
||||
@ -444,7 +457,15 @@
|
||||
"hide-duration-left": "隱藏音樂剩餘時間狀態",
|
||||
"hide-github-button": "隱藏 GitHub 頁面按鈕",
|
||||
"play-on-youtube-music": "顯示 Play on YouTube Music 按鈕",
|
||||
"set-inactivity-timeout": "設定閒置狀態時長"
|
||||
"set-inactivity-timeout": "設定閒置狀態時長",
|
||||
"set-status-display-type": {
|
||||
"label": "狀態文字",
|
||||
"submenu": {
|
||||
"artist": "正在聽 {artist}",
|
||||
"title": "正在聽 {song title}",
|
||||
"youtube-music": "正在聽 YouTube Music"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Discord 狀態",
|
||||
"prompt": {
|
||||
@ -645,8 +666,8 @@
|
||||
"name": "歌曲播放通知"
|
||||
},
|
||||
"performance-improvement": {
|
||||
"description": "使用實驗性的腳本以優化效能",
|
||||
"name": "效能優化 [Beta]"
|
||||
"description": "使用實驗性的腳本以最佳化效能",
|
||||
"name": "效能最佳化 [Beta]"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"description": "允許應用程式切換至子母畫面模式",
|
||||
@ -724,7 +745,7 @@
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "Last.fm 認證失敗\n將隱藏彈窗直到重啟。",
|
||||
"message": "Last.fm 認證失敗\n將隱藏彈出視窗直到重啟。",
|
||||
"title": "認證失敗"
|
||||
}
|
||||
}
|
||||
@ -736,6 +757,7 @@
|
||||
"listenbrainz": {
|
||||
"token": "輸入 ListenBrainz 使用者憑證"
|
||||
},
|
||||
"scrobble-alternative-artist": "使用替代的藝人",
|
||||
"scrobble-alternative-title": "使用替代歌曲標題",
|
||||
"scrobble-other-media": "紀錄其他媒體檔案"
|
||||
},
|
||||
@ -743,7 +765,7 @@
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "Last.fm API 金鑰",
|
||||
"api-secret": "Last.fm API 密鑰"
|
||||
"api-secret": "Last.fm API 金鑰"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
@ -821,6 +843,14 @@
|
||||
"label": "使歌詞完美同步",
|
||||
"tooltip": "更精確的計算下一行歌詞的顯示 (將會降低些許效能)"
|
||||
},
|
||||
"preferred-provider": {
|
||||
"label": "偏好提供者",
|
||||
"none": {
|
||||
"label": "無",
|
||||
"tooltip": "沒有偏好的提供者"
|
||||
},
|
||||
"tooltip": "選擇要使用的預設提供者"
|
||||
},
|
||||
"romanization": {
|
||||
"label": "羅馬拼音化歌詞",
|
||||
"tooltip": "如果歌詞使用不同語言,嘗試使用拉丁文顯示。"
|
||||
@ -853,6 +883,27 @@
|
||||
"description": "為 macOS 使用者新增觸控列支援",
|
||||
"name": "觸控列 (Touchbar) 支援"
|
||||
},
|
||||
"transparent-player": {
|
||||
"description": "讓應用程式視窗變為透明",
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"label": "不透明度",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"label": "類型",
|
||||
"submenu": {
|
||||
"acrylic": "壓克力",
|
||||
"mica": "雲母",
|
||||
"none": "無",
|
||||
"tabbed": "分頁式"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "透明撥放器"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "與 OBS 的 Tuna 外掛連線",
|
||||
"name": "Tuna OBS"
|
||||
|
||||
@ -29,7 +29,7 @@ import { allPlugins, mainPlugins } from 'virtual:plugins';
|
||||
|
||||
import { languageResources } from 'virtual:i18n';
|
||||
|
||||
import config from '@/config';
|
||||
import * as config from '@/config';
|
||||
|
||||
import { refreshMenu, setApplicationMenu } from '@/menu';
|
||||
import { fileExists, injectCSS, injectCSSAsFile } from '@/plugins/utils/main';
|
||||
|
||||
@ -3,7 +3,7 @@ import { type BrowserWindow, ipcMain } from 'electron';
|
||||
import { deepmerge } from 'deepmerge-ts';
|
||||
import { allPlugins, mainPlugins } from 'virtual:plugins';
|
||||
|
||||
import config from '@/config';
|
||||
import * as config from '@/config';
|
||||
import { LoggerPrefix, startPlugin, stopPlugin } from '@/utils';
|
||||
|
||||
import { t } from '@/i18n';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { deepmerge } from 'deepmerge-ts';
|
||||
import { allPlugins } from 'virtual:plugins';
|
||||
|
||||
import config from '@/config';
|
||||
import * as config from '@/config';
|
||||
import { setApplicationMenu } from '@/menu';
|
||||
|
||||
import { LoggerPrefix } from '@/utils';
|
||||
|
||||
@ -3,7 +3,7 @@ import { allPlugins, preloadPlugins } from 'virtual:plugins';
|
||||
|
||||
import { LoggerPrefix, startPlugin, stopPlugin } from '@/utils';
|
||||
|
||||
import config from '@/config';
|
||||
import * as config from '@/config';
|
||||
|
||||
import { t } from '@/i18n';
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ import { allPlugins } from 'virtual:plugins';
|
||||
|
||||
import { languageResources } from 'virtual:i18n';
|
||||
|
||||
import config from './config';
|
||||
import * as config from './config';
|
||||
|
||||
import { restart } from './providers/app-controls';
|
||||
import { startingPages } from './providers/extracted-data';
|
||||
|
||||
@ -35,6 +35,7 @@ export const backend = createBackend<BackendType, APIServerConfig>({
|
||||
ctx.ipc.send('ytmd:setup-repeat-changed-listener');
|
||||
ctx.ipc.send('ytmd:setup-like-changed-listener');
|
||||
ctx.ipc.send('ytmd:setup-volume-changed-listener');
|
||||
ctx.ipc.send('ytmd:setup-shuffle-changed-listener');
|
||||
});
|
||||
|
||||
ctx.ipc.on(
|
||||
@ -69,6 +70,7 @@ export const backend = createBackend<BackendType, APIServerConfig>({
|
||||
// Custom
|
||||
init(backendCtx) {
|
||||
this.app = new Hono();
|
||||
|
||||
const ws = createNodeWebSocket({
|
||||
app: this.app,
|
||||
});
|
||||
@ -120,7 +122,7 @@ export const backend = createBackend<BackendType, APIServerConfig>({
|
||||
() => this.volumeState,
|
||||
);
|
||||
registerAuth(this.app, backendCtx);
|
||||
registerWebsocket(this.app, ws);
|
||||
registerWebsocket(this.app, backendCtx, ws);
|
||||
|
||||
// swagger
|
||||
this.app.openAPIRegistry.registerComponent(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { createRoute, z } from '@hono/zod-openapi';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import getSongControls from '@/providers/song-controls';
|
||||
import { getSongControls } from '@/providers/song-controls';
|
||||
import {
|
||||
LikeType,
|
||||
type RepeatMode,
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import { createRoute } from '@hono/zod-openapi';
|
||||
|
||||
import { type NodeWebSocket } from '@hono/node-ws';
|
||||
@ -15,6 +14,8 @@ import type { WSContext } from 'hono/ws';
|
||||
import type { Context, Next } from 'hono';
|
||||
import type { RepeatMode, VolumeState } from '@/types/datahost-get-state';
|
||||
import type { HonoApp } from '../types';
|
||||
import type { BackendContext } from '@/types/contexts';
|
||||
import type { APIServerConfig } from '@/plugins/api-server/config';
|
||||
|
||||
enum DataTypes {
|
||||
PlayerInfo = 'PLAYER_INFO',
|
||||
@ -23,6 +24,7 @@ enum DataTypes {
|
||||
PositionChanged = 'POSITION_CHANGED',
|
||||
VolumeChanged = 'VOLUME_CHANGED',
|
||||
RepeatChanged = 'REPEAT_CHANGED',
|
||||
ShuffleChanged = 'SHUFFLE_CHANGED',
|
||||
}
|
||||
|
||||
type PlayerState = {
|
||||
@ -32,11 +34,17 @@ type PlayerState = {
|
||||
position: number;
|
||||
volume: number;
|
||||
repeat: RepeatMode;
|
||||
shuffle: boolean;
|
||||
};
|
||||
|
||||
export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
|
||||
export const register = (
|
||||
app: HonoApp,
|
||||
{ ipc }: BackendContext<APIServerConfig>,
|
||||
{ upgradeWebSocket }: NodeWebSocket,
|
||||
) => {
|
||||
let volumeState: VolumeState | undefined = undefined;
|
||||
let repeat: RepeatMode = 'NONE';
|
||||
let shuffle = false;
|
||||
let lastSongInfo: SongInfo | undefined = undefined;
|
||||
|
||||
const sockets = new Set<WSContext<WebSocket>>();
|
||||
@ -51,10 +59,12 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
|
||||
songInfo,
|
||||
volumeState,
|
||||
repeat,
|
||||
shuffle,
|
||||
}: {
|
||||
songInfo?: SongInfo;
|
||||
volumeState?: VolumeState;
|
||||
repeat: RepeatMode;
|
||||
shuffle: boolean;
|
||||
}): PlayerState => ({
|
||||
song: songInfo,
|
||||
isPlaying: songInfo ? !songInfo.isPaused : false,
|
||||
@ -62,6 +72,7 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
|
||||
position: songInfo?.elapsedSeconds ?? 0,
|
||||
volume: volumeState?.state ?? 100,
|
||||
repeat,
|
||||
shuffle,
|
||||
});
|
||||
|
||||
registerCallback((songInfo, event) => {
|
||||
@ -83,7 +94,7 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
|
||||
lastSongInfo = { ...songInfo };
|
||||
});
|
||||
|
||||
ipcMain.on('ytmd:volume-changed', (_, newVolumeState: VolumeState) => {
|
||||
ipc.on('ytmd:volume-changed', (newVolumeState: VolumeState) => {
|
||||
volumeState = newVolumeState;
|
||||
send(DataTypes.VolumeChanged, {
|
||||
volume: volumeState.state,
|
||||
@ -91,15 +102,20 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.on('ytmd:repeat-changed', (_, mode: RepeatMode) => {
|
||||
ipc.on('ytmd:repeat-changed', (mode: RepeatMode) => {
|
||||
repeat = mode;
|
||||
send(DataTypes.RepeatChanged, { repeat });
|
||||
});
|
||||
|
||||
ipcMain.on('ytmd:seeked', (_, t: number) => {
|
||||
ipc.on('ytmd:seeked', (t: number) => {
|
||||
send(DataTypes.PositionChanged, { position: t });
|
||||
});
|
||||
|
||||
ipc.on('ytmd:shuffle-changed', (newShuffle: boolean) => {
|
||||
shuffle = newShuffle;
|
||||
send(DataTypes.ShuffleChanged, { shuffle });
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
method: 'get',
|
||||
@ -112,7 +128,7 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
|
||||
},
|
||||
},
|
||||
}),
|
||||
nodeWebSocket.upgradeWebSocket(() => ({
|
||||
upgradeWebSocket(() => ({
|
||||
onOpen(_, ws) {
|
||||
// "Unsafe argument of type `WSContext<WebSocket>` assigned to a parameter of type `WSContext<WebSocket>`. (@typescript-eslint/no-unsafe-argument)" ????? what?
|
||||
sockets.add(ws as WSContext<WebSocket>);
|
||||
@ -124,6 +140,7 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
|
||||
songInfo: lastSongInfo,
|
||||
volumeState,
|
||||
repeat,
|
||||
shuffle,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
@ -1,17 +1,15 @@
|
||||
import net from 'net';
|
||||
import * as net from 'node:net';
|
||||
|
||||
import { SocksClient, type SocksClientOptions } from 'socks';
|
||||
|
||||
import is from 'electron-is';
|
||||
|
||||
import { createBackend, LoggerPrefix } from '@/utils';
|
||||
|
||||
import { type BackendType } from './types';
|
||||
|
||||
import config from '@/config';
|
||||
import * as config from '@/config';
|
||||
|
||||
import { type AuthProxyConfig, defaultAuthProxyConfig } from '../config';
|
||||
|
||||
import type { BackendType } from './types';
|
||||
import type { BackendContext } from '@/types/contexts';
|
||||
|
||||
// Parsing the upstream authentication SOCK proxy URL
|
||||
|
||||
@ -2,7 +2,7 @@ import { createSignal } from 'solid-js';
|
||||
|
||||
import { render } from 'solid-js/web';
|
||||
|
||||
import defaultConfig from '@/config/defaults';
|
||||
import { defaultConfig } from '@/config/defaults';
|
||||
import { getSongMenu } from '@/providers/dom-elements';
|
||||
import { getSongInfo } from '@/providers/song-info-front';
|
||||
import { t } from '@/i18n';
|
||||
|
||||
@ -7,7 +7,7 @@ import previousIcon from '@assets/media-icons-black/previous.png?asset&asarUnpac
|
||||
|
||||
import { notificationImage, secondsToMinutes, ToastStyles } from './utils';
|
||||
|
||||
import getSongControls from '@/providers/song-controls';
|
||||
import { getSongControls } from '@/providers/song-controls';
|
||||
import {
|
||||
registerCallback,
|
||||
type SongInfo,
|
||||
|
||||
@ -2,8 +2,8 @@ import { type BrowserWindow, globalShortcut } from 'electron';
|
||||
import is from 'electron-is';
|
||||
import { register as registerElectronLocalShortcut } from 'electron-localshortcut';
|
||||
|
||||
import registerMPRIS from './mpris';
|
||||
import getSongControls from '@/providers/song-controls';
|
||||
import { registerMPRIS } from './mpris';
|
||||
import { getSongControls } from '@/providers/song-controls';
|
||||
|
||||
import type { ShortcutMappingType, ShortcutsPluginConfig } from './index';
|
||||
|
||||
|
||||
@ -19,8 +19,8 @@ import {
|
||||
type SongInfo,
|
||||
SongInfoEvent,
|
||||
} from '@/providers/song-info';
|
||||
import getSongControls from '@/providers/song-controls';
|
||||
import config from '@/config';
|
||||
import { getSongControls } from '@/providers/song-controls';
|
||||
import * as config from '@/config';
|
||||
import { LoggerPrefix } from '@/utils';
|
||||
|
||||
import type { RepeatMode, VolumeState } from '@/types/datahost-get-state';
|
||||
@ -84,7 +84,7 @@ function setupMPRIS() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
function registerMPRIS(win: BrowserWindow) {
|
||||
export function registerMPRIS(win: BrowserWindow) {
|
||||
const songControls = getSongControls(win);
|
||||
const {
|
||||
playPause,
|
||||
@ -363,5 +363,3 @@ function registerMPRIS(win: BrowserWindow) {
|
||||
console.trace(error);
|
||||
}
|
||||
}
|
||||
|
||||
export default registerMPRIS;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { t } from '@/i18n';
|
||||
|
||||
import { providerNames } from './providers';
|
||||
|
||||
import type { MenuItemConstructorOptions } from 'electron';
|
||||
import type { MenuContext } from '@/types/contexts';
|
||||
import type { SyncedLyricsPluginConfig } from './types';
|
||||
@ -10,6 +12,35 @@ export const menu = async (
|
||||
const config = await ctx.getConfig();
|
||||
|
||||
return [
|
||||
{
|
||||
label: t('plugins.synced-lyrics.menu.preferred-provider.label'),
|
||||
toolTip: t('plugins.synced-lyrics.menu.preferred-provider.tooltip'),
|
||||
type: 'submenu',
|
||||
submenu: [
|
||||
{
|
||||
label: t('plugins.synced-lyrics.menu.preferred-provider.none.label'),
|
||||
toolTip: t(
|
||||
'plugins.synced-lyrics.menu.preferred-provider.none.tooltip',
|
||||
),
|
||||
type: 'radio',
|
||||
checked: config.preferredProvider === undefined,
|
||||
click() {
|
||||
ctx.setConfig({ preferredProvider: undefined });
|
||||
},
|
||||
},
|
||||
...providerNames.map(
|
||||
(provider) =>
|
||||
({
|
||||
label: provider,
|
||||
type: 'radio',
|
||||
checked: config.preferredProvider === provider,
|
||||
click() {
|
||||
ctx.setConfig({ preferredProvider: provider });
|
||||
},
|
||||
}) as const,
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('plugins.synced-lyrics.menu.precise-timing.label'),
|
||||
toolTip: t('plugins.synced-lyrics.menu.precise-timing.tooltip'),
|
||||
@ -93,47 +124,23 @@ export const menu = async (
|
||||
toolTip: t('plugins.synced-lyrics.menu.default-text-string.tooltip'),
|
||||
type: 'submenu',
|
||||
submenu: [
|
||||
{
|
||||
label: '♪',
|
||||
type: 'radio',
|
||||
checked: config.defaultTextString === '♪',
|
||||
click() {
|
||||
ctx.setConfig({
|
||||
defaultTextString: '♪',
|
||||
});
|
||||
},
|
||||
{ label: '♪', value: '♪' },
|
||||
{ label: '" "', value: ' ' },
|
||||
{ label: '...', value: ['.', '..', '...'] },
|
||||
{ label: '•••', value: ['•', '••', '•••'] },
|
||||
{ label: '———', value: '———' },
|
||||
].map(({ label, value }) => ({
|
||||
label,
|
||||
type: 'radio',
|
||||
checked:
|
||||
typeof value === 'string'
|
||||
? config.defaultTextString === value
|
||||
: JSON.stringify(config.defaultTextString) ===
|
||||
JSON.stringify(value),
|
||||
click() {
|
||||
ctx.setConfig({ defaultTextString: value });
|
||||
},
|
||||
{
|
||||
label: '" "',
|
||||
type: 'radio',
|
||||
checked: config.defaultTextString === ' ',
|
||||
click() {
|
||||
ctx.setConfig({
|
||||
defaultTextString: ' ',
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '...',
|
||||
type: 'radio',
|
||||
checked: config.defaultTextString === '...',
|
||||
click() {
|
||||
ctx.setConfig({
|
||||
defaultTextString: '...',
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '———',
|
||||
type: 'radio',
|
||||
checked: config.defaultTextString === '———',
|
||||
click() {
|
||||
ctx.setConfig({
|
||||
defaultTextString: '———',
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
})),
|
||||
},
|
||||
{
|
||||
label: t('plugins.synced-lyrics.menu.romanization.label'),
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { z } from 'zod';
|
||||
import * as z from 'zod';
|
||||
|
||||
import { LRC } from '../parsers/lrc';
|
||||
import { netFetch } from '../renderer';
|
||||
|
||||
@ -1,191 +1,21 @@
|
||||
import { createStore } from 'solid-js/store';
|
||||
import * as z from 'zod';
|
||||
|
||||
import { createMemo } from 'solid-js';
|
||||
import type { LyricResult } from '../types';
|
||||
|
||||
import { LRCLib } from './LRCLib';
|
||||
import { LyricsGenius } from './LyricsGenius';
|
||||
import { MusixMatch } from './MusixMatch';
|
||||
import { YTMusic } from './YTMusic';
|
||||
export enum ProviderNames {
|
||||
YTMusic = 'YTMusic',
|
||||
LRCLib = 'LRCLib',
|
||||
MusixMatch = 'MusixMatch',
|
||||
LyricsGenius = 'LyricsGenius',
|
||||
// Megalobiz = 'Megalobiz',
|
||||
}
|
||||
|
||||
import { getSongInfo } from '@/providers/song-info-front';
|
||||
|
||||
import type { LyricProvider, LyricResult } from '../types';
|
||||
import type { SongInfo } from '@/providers/song-info';
|
||||
|
||||
export const providers = {
|
||||
YTMusic: new YTMusic(),
|
||||
LRCLib: new LRCLib(),
|
||||
MusixMatch: new MusixMatch(),
|
||||
LyricsGenius: new LyricsGenius(),
|
||||
// Megalobiz: new Megalobiz(), // Disabled because it is too unstable and slow
|
||||
} as const;
|
||||
|
||||
export type ProviderName = keyof typeof providers;
|
||||
export const providerNames = Object.keys(providers) as ProviderName[];
|
||||
export const ProviderNameSchema = z.enum(ProviderNames);
|
||||
export type ProviderName = z.infer<typeof ProviderNameSchema>;
|
||||
export const providerNames = ProviderNameSchema.options;
|
||||
|
||||
export type ProviderState = {
|
||||
state: 'fetching' | 'done' | 'error';
|
||||
data: LyricResult | null;
|
||||
error: Error | null;
|
||||
};
|
||||
|
||||
type LyricsStore = {
|
||||
provider: ProviderName;
|
||||
current: ProviderState;
|
||||
lyrics: Record<ProviderName, ProviderState>;
|
||||
};
|
||||
|
||||
const initialData = () =>
|
||||
providerNames.reduce(
|
||||
(acc, name) => {
|
||||
acc[name] = { state: 'fetching', data: null, error: null };
|
||||
return acc;
|
||||
},
|
||||
{} as LyricsStore['lyrics'],
|
||||
);
|
||||
|
||||
export const [lyricsStore, setLyricsStore] = createStore<LyricsStore>({
|
||||
provider: providerNames[0],
|
||||
lyrics: initialData(),
|
||||
get current(): ProviderState {
|
||||
return this.lyrics[this.provider];
|
||||
},
|
||||
});
|
||||
|
||||
export const currentLyrics = createMemo(() => {
|
||||
const provider = lyricsStore.provider;
|
||||
return lyricsStore.lyrics[provider];
|
||||
});
|
||||
|
||||
type VideoId = string;
|
||||
|
||||
type SearchCacheData = Record<ProviderName, ProviderState>;
|
||||
interface SearchCache {
|
||||
state: 'loading' | 'done';
|
||||
data: SearchCacheData;
|
||||
}
|
||||
|
||||
// TODO: Maybe use localStorage for the cache.
|
||||
const searchCache = new Map<VideoId, SearchCache>();
|
||||
export const fetchLyrics = (info: SongInfo) => {
|
||||
if (searchCache.has(info.videoId)) {
|
||||
const cache = searchCache.get(info.videoId)!;
|
||||
|
||||
if (cache.state === 'loading') {
|
||||
setTimeout(() => {
|
||||
fetchLyrics(info);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (getSongInfo().videoId === info.videoId) {
|
||||
setLyricsStore('lyrics', () => {
|
||||
// weird bug with solid-js
|
||||
return JSON.parse(JSON.stringify(cache.data)) as typeof cache.data;
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const cache: SearchCache = {
|
||||
state: 'loading',
|
||||
data: initialData(),
|
||||
};
|
||||
|
||||
searchCache.set(info.videoId, cache);
|
||||
if (getSongInfo().videoId === info.videoId) {
|
||||
setLyricsStore('lyrics', () => {
|
||||
// weird bug with solid-js
|
||||
return JSON.parse(JSON.stringify(cache.data)) as typeof cache.data;
|
||||
});
|
||||
}
|
||||
|
||||
const tasks: Promise<void>[] = [];
|
||||
|
||||
// prettier-ignore
|
||||
for (
|
||||
const [providerName, provider] of Object.entries(providers) as [
|
||||
ProviderName,
|
||||
LyricProvider,
|
||||
][]
|
||||
) {
|
||||
const pCache = cache.data[providerName];
|
||||
|
||||
tasks.push(
|
||||
provider
|
||||
.search(info)
|
||||
.then((res) => {
|
||||
pCache.state = 'done';
|
||||
pCache.data = res;
|
||||
|
||||
if (getSongInfo().videoId === info.videoId) {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
return {
|
||||
...old,
|
||||
[providerName]: {
|
||||
state: 'done',
|
||||
data: res ? { ...res } : null,
|
||||
error: null,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
pCache.state = 'error';
|
||||
pCache.error = error;
|
||||
|
||||
console.error(error);
|
||||
|
||||
if (getSongInfo().videoId === info.videoId) {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
return {
|
||||
...old,
|
||||
[providerName]: { state: 'error', error, data: null },
|
||||
};
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Promise.allSettled(tasks).then(() => {
|
||||
cache.state = 'done';
|
||||
searchCache.set(info.videoId, cache);
|
||||
});
|
||||
};
|
||||
|
||||
export const retrySearch = (provider: ProviderName, info: SongInfo) => {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
const pCache = {
|
||||
state: 'fetching',
|
||||
data: null,
|
||||
error: null,
|
||||
};
|
||||
|
||||
return {
|
||||
...old,
|
||||
[provider]: pCache,
|
||||
};
|
||||
});
|
||||
|
||||
providers[provider]
|
||||
.search(info)
|
||||
.then((res) => {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
return {
|
||||
...old,
|
||||
[provider]: { state: 'done', data: res, error: null },
|
||||
};
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
return {
|
||||
...old,
|
||||
[provider]: { state: 'error', data: null, error },
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
13
src/plugins/synced-lyrics/providers/renderer.ts
Normal file
13
src/plugins/synced-lyrics/providers/renderer.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { ProviderNames } from './index';
|
||||
import { YTMusic } from './YTMusic';
|
||||
import { LRCLib } from './LRCLib';
|
||||
import { MusixMatch } from './MusixMatch';
|
||||
import { LyricsGenius } from './LyricsGenius';
|
||||
|
||||
export const providers = {
|
||||
[ProviderNames.YTMusic]: new YTMusic(),
|
||||
[ProviderNames.LRCLib]: new LRCLib(),
|
||||
[ProviderNames.MusixMatch]: new MusixMatch(),
|
||||
[ProviderNames.LyricsGenius]: new LyricsGenius(),
|
||||
// [ProviderNames.Megalobiz]: new Megalobiz(), // Disabled because it is too unstable and slow
|
||||
} as const;
|
||||
@ -2,7 +2,7 @@ import { t } from '@/i18n';
|
||||
|
||||
import { getSongInfo } from '@/providers/song-info-front';
|
||||
|
||||
import { lyricsStore, retrySearch } from '../../providers';
|
||||
import { lyricsStore, retrySearch } from '../store';
|
||||
|
||||
interface ErrorDisplayProps {
|
||||
error: Error;
|
||||
|
||||
@ -11,18 +11,24 @@ import {
|
||||
Switch,
|
||||
} from 'solid-js';
|
||||
|
||||
import * as z from 'zod';
|
||||
|
||||
import {
|
||||
currentLyrics,
|
||||
lyricsStore,
|
||||
type ProviderName,
|
||||
providerNames,
|
||||
ProviderNameSchema,
|
||||
type ProviderState,
|
||||
setLyricsStore,
|
||||
} from '../../providers';
|
||||
|
||||
import { currentLyrics, lyricsStore, setLyricsStore } from '../store';
|
||||
import { _ytAPI } from '../index';
|
||||
import { config } from '../renderer';
|
||||
|
||||
import type { YtIcons } from '@/types/icons';
|
||||
import type { PlayerAPIEvents } from '@/types/player-api-events';
|
||||
|
||||
const LocalStorageSchema = z.object({
|
||||
provider: ProviderNameSchema,
|
||||
});
|
||||
|
||||
export const providerIdx = createMemo(() =>
|
||||
providerNames.indexOf(lyricsStore.provider),
|
||||
@ -45,11 +51,19 @@ const providerBias = (p: ProviderName) =>
|
||||
(lyricsStore.lyrics[p].data?.lyrics ? 1 : -1);
|
||||
|
||||
const pickBestProvider = () => {
|
||||
const preferred = config()?.preferredProvider;
|
||||
if (preferred) {
|
||||
const data = lyricsStore.lyrics[preferred].data;
|
||||
if (Array.isArray(data?.lines) || data?.lyrics) {
|
||||
return { provider: preferred, force: true };
|
||||
}
|
||||
}
|
||||
|
||||
const providers = Array.from(providerNames);
|
||||
|
||||
providers.sort((a, b) => providerBias(b) - providerBias(a));
|
||||
|
||||
return providers[0];
|
||||
return { provider: providers[0], force: false };
|
||||
};
|
||||
|
||||
const [hasManuallySwitchedProvider, setHasManuallySwitchedProvider] =
|
||||
@ -58,34 +72,91 @@ const [hasManuallySwitchedProvider, setHasManuallySwitchedProvider] =
|
||||
export const LyricsPicker = (props: {
|
||||
setStickRef: Setter<HTMLElement | null>;
|
||||
}) => {
|
||||
const [videoId, setVideoId] = createSignal<string | null>(null);
|
||||
const [starredProvider, setStarredProvider] =
|
||||
createSignal<ProviderName | null>(null);
|
||||
|
||||
createEffect(() => {
|
||||
const id = videoId();
|
||||
if (id === null) {
|
||||
setStarredProvider(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const key = `ytmd-sl-starred-${id}`;
|
||||
const value = localStorage.getItem(key);
|
||||
if (!value) {
|
||||
setStarredProvider(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const parseResult = LocalStorageSchema.safeParse(JSON.parse(value));
|
||||
if (parseResult.success) {
|
||||
setLyricsStore('provider', parseResult.data.provider);
|
||||
setStarredProvider(parseResult.data.provider);
|
||||
} else {
|
||||
setStarredProvider(null);
|
||||
}
|
||||
});
|
||||
|
||||
const toggleStar = () => {
|
||||
const id = videoId();
|
||||
if (id === null) return;
|
||||
|
||||
const key = `ytmd-sl-starred-${id}`;
|
||||
|
||||
setStarredProvider((starredProvider) => {
|
||||
if (lyricsStore.provider === starredProvider) {
|
||||
localStorage.removeItem(key);
|
||||
return null;
|
||||
}
|
||||
|
||||
const provider = lyricsStore.provider;
|
||||
localStorage.setItem(key, JSON.stringify({ provider }));
|
||||
|
||||
return provider;
|
||||
});
|
||||
};
|
||||
|
||||
const videoDataChangeHandler = (
|
||||
name: string,
|
||||
{ videoId }: PlayerAPIEvents['videodatachange']['value'],
|
||||
) => {
|
||||
setVideoId(videoId);
|
||||
|
||||
if (name !== 'dataloaded') return;
|
||||
setHasManuallySwitchedProvider(false);
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
{
|
||||
onMount(() => _ytAPI?.addEventListener('videodatachange', videoDataChangeHandler));
|
||||
onCleanup(() => _ytAPI?.removeEventListener('videodatachange', videoDataChangeHandler));
|
||||
}
|
||||
|
||||
createEffect(() => {
|
||||
// fallback to the next source, if the current one has an error
|
||||
if (!hasManuallySwitchedProvider()) {
|
||||
const bestProvider = pickBestProvider();
|
||||
const starred = starredProvider();
|
||||
if (starred !== null) {
|
||||
setLyricsStore('provider', starred);
|
||||
return;
|
||||
}
|
||||
|
||||
const allProvidersFailed = providerNames.every((p) =>
|
||||
shouldSwitchProvider(lyricsStore.lyrics[p]),
|
||||
);
|
||||
if (allProvidersFailed) return;
|
||||
|
||||
if (providerBias(lyricsStore.provider) < providerBias(bestProvider)) {
|
||||
setLyricsStore('provider', bestProvider);
|
||||
const { provider, force } = pickBestProvider();
|
||||
if (
|
||||
force ||
|
||||
providerBias(lyricsStore.provider) < providerBias(provider)
|
||||
) {
|
||||
setLyricsStore('provider', provider);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
const videoDataChangeHandler = (name: string) => {
|
||||
if (name !== 'dataloaded') return;
|
||||
setHasManuallySwitchedProvider(false);
|
||||
};
|
||||
|
||||
_ytAPI?.addEventListener('videodatachange', videoDataChangeHandler);
|
||||
onCleanup(() =>
|
||||
_ytAPI?.removeEventListener('videodatachange', videoDataChangeHandler),
|
||||
);
|
||||
});
|
||||
|
||||
const next = () => {
|
||||
setHasManuallySwitchedProvider(true);
|
||||
setLyricsStore('provider', (prevProvider) => {
|
||||
@ -176,9 +247,9 @@ export const LyricsPicker = (props: {
|
||||
/>
|
||||
</Match>
|
||||
<Match when={currentLyrics().state === 'error'}>
|
||||
<yt-icon-button
|
||||
<yt-icon
|
||||
icon={errorIcon}
|
||||
style={{ padding: '5px', transform: 'scale(0.5)' }}
|
||||
style={{ padding: '5px', transform: 'scale(0.8)' }}
|
||||
tabindex="-1"
|
||||
/>
|
||||
</Match>
|
||||
@ -189,9 +260,9 @@ export const LyricsPicker = (props: {
|
||||
currentLyrics().data?.lyrics)
|
||||
}
|
||||
>
|
||||
<yt-icon-button
|
||||
<yt-icon
|
||||
icon={successIcon}
|
||||
style={{ padding: '5px', transform: 'scale(0.5)' }}
|
||||
style={{ padding: '5px', transform: 'scale(0.8)' }}
|
||||
tabindex="-1"
|
||||
/>
|
||||
</Match>
|
||||
@ -202,9 +273,9 @@ export const LyricsPicker = (props: {
|
||||
!currentLyrics().data?.lyrics
|
||||
}
|
||||
>
|
||||
<yt-icon-button
|
||||
<yt-icon
|
||||
icon={notFoundIcon}
|
||||
style={{ padding: '5px', transform: 'scale(0.5)' }}
|
||||
style={{ padding: '5px', transform: 'scale(0.8)' }}
|
||||
tabindex="-1"
|
||||
/>
|
||||
</Match>
|
||||
@ -213,6 +284,20 @@ export const LyricsPicker = (props: {
|
||||
class="description ytmusic-description-shelf-renderer"
|
||||
text={{ runs: [{ text: provider() }] }}
|
||||
/>
|
||||
<yt-icon
|
||||
icon={
|
||||
starredProvider() === provider()
|
||||
? 'yt-sys-icons:star-filled'
|
||||
: 'yt-sys-icons:star'
|
||||
}
|
||||
onClick={toggleStar}
|
||||
style={{
|
||||
padding: '5px',
|
||||
transform: 'scale(0.8)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
tabindex="-1"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Index>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { createEffect, createMemo, For, Show, createSignal } from 'solid-js';
|
||||
import { createEffect, For, Show, createSignal, createMemo } from 'solid-js';
|
||||
|
||||
import { type VirtualizerHandle } from 'virtua/solid';
|
||||
|
||||
import { type LineLyrics } from '@/plugins/synced-lyrics/types';
|
||||
|
||||
import { config } from '../renderer';
|
||||
import { config, currentTime } from '../renderer';
|
||||
import { _ytAPI } from '..';
|
||||
|
||||
import { canonicalize, romanize, simplifyUnicode } from '../utils';
|
||||
@ -17,37 +17,84 @@ interface SyncedLineProps {
|
||||
status: 'upcoming' | 'current' | 'previous';
|
||||
}
|
||||
|
||||
export const SyncedLine = (props: SyncedLineProps) => {
|
||||
const text = createMemo(() => {
|
||||
if (!props.line.text.trim()) {
|
||||
return config()?.defaultTextString ?? '';
|
||||
}
|
||||
|
||||
return props.line.text;
|
||||
const EmptyLine = (props: SyncedLineProps) => {
|
||||
const states = createMemo(() => {
|
||||
const defaultText = config()?.defaultTextString ?? '';
|
||||
return Array.isArray(defaultText) ? defaultText : [defaultText];
|
||||
});
|
||||
|
||||
const [romanization, setRomanization] = createSignal('');
|
||||
const index = createMemo(() => {
|
||||
const progress = currentTime() - props.line.timeInMs;
|
||||
const total = props.line.duration;
|
||||
|
||||
const percentage = Math.min(1, progress / total);
|
||||
return Math.max(0, Math.floor((states().length - 1) * percentage));
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
class={`synced-line ${props.status}`}
|
||||
onClick={() => {
|
||||
_ytAPI?.seekTo((props.line.timeInMs + 10) / 1000);
|
||||
}}
|
||||
>
|
||||
<div class="description ytmusic-description-shelf-renderer" dir="auto">
|
||||
<yt-formatted-string
|
||||
text={{
|
||||
runs: [
|
||||
{
|
||||
text: config()?.showTimeCodes ? `[${props.line.time}] ` : '',
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="text-lyrics">
|
||||
<span>
|
||||
<span>
|
||||
<Show
|
||||
fallback={
|
||||
<yt-formatted-string
|
||||
text={{ runs: [{ text: states()[0] }] }}
|
||||
/>
|
||||
}
|
||||
when={states().length > 1}
|
||||
>
|
||||
<yt-formatted-string
|
||||
text={{
|
||||
runs: [
|
||||
{
|
||||
text: states().at(
|
||||
props.status === 'current' ? index() : -1,
|
||||
)!,
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
</Show>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const SyncedLine = (props: SyncedLineProps) => {
|
||||
const text = createMemo(() => props.line.text.trim());
|
||||
|
||||
const [romanization, setRomanization] = createSignal('');
|
||||
createEffect(() => {
|
||||
const input = canonicalize(text());
|
||||
if (!config()?.romanization) return;
|
||||
|
||||
const input = canonicalize(text());
|
||||
romanize(input).then((result) => {
|
||||
setRomanization(canonicalize(result));
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<Show
|
||||
fallback={
|
||||
<yt-formatted-string
|
||||
text={{
|
||||
runs: [{ text: '' }],
|
||||
}}
|
||||
/>
|
||||
}
|
||||
when={text()}
|
||||
>
|
||||
<Show fallback={<EmptyLine {...props} />} when={text()}>
|
||||
<div
|
||||
class={`synced-line ${props.status}`}
|
||||
onClick={() => {
|
||||
|
||||
@ -3,8 +3,7 @@ import { waitForElement } from '@/utils/wait-for-element';
|
||||
|
||||
import { selectors, tabStates } from './utils';
|
||||
import { setConfig, setCurrentTime } from './renderer';
|
||||
|
||||
import { fetchLyrics } from '../providers';
|
||||
import { fetchLyrics } from './store';
|
||||
|
||||
import type { RendererContext } from '@/types/contexts';
|
||||
import type { YoutubePlayer } from '@/types/youtube-player';
|
||||
|
||||
@ -20,7 +20,7 @@ import {
|
||||
PlainLyrics,
|
||||
} from './components';
|
||||
|
||||
import { currentLyrics } from '../providers';
|
||||
import { currentLyrics } from './store';
|
||||
|
||||
import type { LineLyrics, SyncedLyricsPluginConfig } from '../types';
|
||||
|
||||
|
||||
175
src/plugins/synced-lyrics/renderer/store.ts
Normal file
175
src/plugins/synced-lyrics/renderer/store.ts
Normal file
@ -0,0 +1,175 @@
|
||||
import { createStore } from 'solid-js/store';
|
||||
import { createMemo } from 'solid-js';
|
||||
|
||||
import { getSongInfo } from '@/providers/song-info-front';
|
||||
|
||||
import {
|
||||
type ProviderName,
|
||||
providerNames,
|
||||
type ProviderState,
|
||||
} from '../providers';
|
||||
import { providers } from '../providers/renderer';
|
||||
|
||||
import type { LyricProvider } from '../types';
|
||||
import type { SongInfo } from '@/providers/song-info';
|
||||
|
||||
type LyricsStore = {
|
||||
provider: ProviderName;
|
||||
current: ProviderState;
|
||||
lyrics: Record<ProviderName, ProviderState>;
|
||||
};
|
||||
|
||||
const initialData = () =>
|
||||
providerNames.reduce(
|
||||
(acc, name) => {
|
||||
acc[name] = { state: 'fetching', data: null, error: null };
|
||||
return acc;
|
||||
},
|
||||
{} as LyricsStore['lyrics'],
|
||||
);
|
||||
|
||||
export const [lyricsStore, setLyricsStore] = createStore<LyricsStore>({
|
||||
provider: providerNames[0],
|
||||
lyrics: initialData(),
|
||||
get current(): ProviderState {
|
||||
return this.lyrics[this.provider];
|
||||
},
|
||||
});
|
||||
|
||||
export const currentLyrics = createMemo(() => {
|
||||
const provider = lyricsStore.provider;
|
||||
return lyricsStore.lyrics[provider];
|
||||
});
|
||||
|
||||
type VideoId = string;
|
||||
|
||||
type SearchCacheData = Record<ProviderName, ProviderState>;
|
||||
interface SearchCache {
|
||||
state: 'loading' | 'done';
|
||||
data: SearchCacheData;
|
||||
}
|
||||
|
||||
// TODO: Maybe use localStorage for the cache.
|
||||
const searchCache = new Map<VideoId, SearchCache>();
|
||||
export const fetchLyrics = (info: SongInfo) => {
|
||||
if (searchCache.has(info.videoId)) {
|
||||
const cache = searchCache.get(info.videoId)!;
|
||||
|
||||
if (cache.state === 'loading') {
|
||||
setTimeout(() => {
|
||||
fetchLyrics(info);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (getSongInfo().videoId === info.videoId) {
|
||||
setLyricsStore('lyrics', () => {
|
||||
// weird bug with solid-js
|
||||
return JSON.parse(JSON.stringify(cache.data)) as typeof cache.data;
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const cache: SearchCache = {
|
||||
state: 'loading',
|
||||
data: initialData(),
|
||||
};
|
||||
|
||||
searchCache.set(info.videoId, cache);
|
||||
if (getSongInfo().videoId === info.videoId) {
|
||||
setLyricsStore('lyrics', () => {
|
||||
// weird bug with solid-js
|
||||
return JSON.parse(JSON.stringify(cache.data)) as typeof cache.data;
|
||||
});
|
||||
}
|
||||
|
||||
const tasks: Promise<void>[] = [];
|
||||
|
||||
// prettier-ignore
|
||||
for (
|
||||
const [providerName, provider] of Object.entries(providers) as [
|
||||
ProviderName,
|
||||
LyricProvider,
|
||||
][]
|
||||
) {
|
||||
const pCache = cache.data[providerName];
|
||||
|
||||
tasks.push(
|
||||
provider
|
||||
.search(info)
|
||||
.then((res) => {
|
||||
pCache.state = 'done';
|
||||
pCache.data = res;
|
||||
|
||||
if (getSongInfo().videoId === info.videoId) {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
return {
|
||||
...old,
|
||||
[providerName]: {
|
||||
state: 'done',
|
||||
data: res ? { ...res } : null,
|
||||
error: null,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
pCache.state = 'error';
|
||||
pCache.error = error;
|
||||
|
||||
console.error(error);
|
||||
|
||||
if (getSongInfo().videoId === info.videoId) {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
return {
|
||||
...old,
|
||||
[providerName]: { state: 'error', error, data: null },
|
||||
};
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Promise.allSettled(tasks).then(() => {
|
||||
cache.state = 'done';
|
||||
searchCache.set(info.videoId, cache);
|
||||
});
|
||||
};
|
||||
|
||||
export const retrySearch = (provider: ProviderName, info: SongInfo) => {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
const pCache = {
|
||||
state: 'fetching',
|
||||
data: null,
|
||||
error: null,
|
||||
};
|
||||
|
||||
return {
|
||||
...old,
|
||||
[provider]: pCache,
|
||||
};
|
||||
});
|
||||
|
||||
providers[provider]
|
||||
.search(info)
|
||||
.then((res) => {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
return {
|
||||
...old,
|
||||
[provider]: { state: 'done', data: res, error: null },
|
||||
};
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
setLyricsStore('lyrics', (old) => {
|
||||
return {
|
||||
...old,
|
||||
[provider]: { state: 'error', data: null, error },
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -1,10 +1,12 @@
|
||||
import type { SongInfo } from '@/providers/song-info';
|
||||
import type { ProviderName } from './providers';
|
||||
|
||||
export type SyncedLyricsPluginConfig = {
|
||||
enabled: boolean;
|
||||
preferredProvider?: ProviderName;
|
||||
preciseTiming: boolean;
|
||||
showTimeCodes: boolean;
|
||||
defaultTextString: string;
|
||||
defaultTextString: string | string[];
|
||||
showLyricsEvenIfInexact: boolean;
|
||||
lineEffect: LineEffect;
|
||||
romanization: boolean;
|
||||
|
||||
@ -7,7 +7,7 @@ import nextIcon from '@assets/media-icons-black/next.png?asset&asarUnpack';
|
||||
import previousIcon from '@assets/media-icons-black/previous.png?asset&asarUnpack';
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
import getSongControls from '@/providers/song-controls';
|
||||
import { getSongControls } from '@/providers/song-controls';
|
||||
import {
|
||||
registerCallback,
|
||||
type SongInfo,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { nativeImage, type NativeImage, TouchBar } from 'electron';
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
import getSongControls from '@/providers/song-controls';
|
||||
import { getSongControls } from '@/providers/song-controls';
|
||||
import { registerCallback, SongInfoEvent } from '@/providers/song-info';
|
||||
import { t } from '@/i18n';
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ const typeList = Object.values(MaterialType);
|
||||
export default createPlugin({
|
||||
name: () => t('plugins.transparent-player.name'),
|
||||
description: () => t('plugins.transparent-player.description'),
|
||||
addedVersion: '3.10.x',
|
||||
addedVersion: '3.11.x',
|
||||
restartNeeded: true,
|
||||
platform: Platform.Windows,
|
||||
config: defaultConfig,
|
||||
|
||||
@ -314,38 +314,37 @@ export default createPlugin({
|
||||
};
|
||||
|
||||
if (config.mode !== 'native' && config.mode != 'disabled') {
|
||||
document
|
||||
.querySelector<HTMLVideoElement>('#player')
|
||||
?.prepend(switchButtonContainer);
|
||||
setTimeout(() => {
|
||||
const playerSelector =
|
||||
document.querySelector<HTMLVideoElement>('#player');
|
||||
if (!playerSelector) return;
|
||||
|
||||
setVideoState(!config.hideVideo);
|
||||
forcePlaybackMode();
|
||||
// Fix black video
|
||||
if (video) {
|
||||
video.style.height = 'auto';
|
||||
}
|
||||
|
||||
video?.addEventListener('ytmd:src-changed', videoStarted);
|
||||
|
||||
observeThumbnail();
|
||||
videoStarted();
|
||||
|
||||
switch (config.align) {
|
||||
case 'right': {
|
||||
switchButtonContainer.style.justifyContent = 'flex-end';
|
||||
return;
|
||||
playerSelector.prepend(switchButtonContainer);
|
||||
setVideoState(!config.hideVideo);
|
||||
forcePlaybackMode();
|
||||
if (video) {
|
||||
video.style.height = 'auto';
|
||||
}
|
||||
video?.addEventListener('ytmd:src-changed', videoStarted);
|
||||
observeThumbnail();
|
||||
videoStarted();
|
||||
switch (config.align) {
|
||||
case 'right': {
|
||||
switchButtonContainer.style.justifyContent = 'flex-end';
|
||||
return;
|
||||
}
|
||||
|
||||
case 'middle': {
|
||||
switchButtonContainer.style.justifyContent = 'center';
|
||||
return;
|
||||
}
|
||||
case 'middle': {
|
||||
switchButtonContainer.style.justifyContent = 'center';
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
case 'left': {
|
||||
switchButtonContainer.style.justifyContent = 'flex-start';
|
||||
default:
|
||||
case 'left': {
|
||||
switchButtonContainer.style.justifyContent = 'flex-start';
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
},
|
||||
onConfigChange(newConfig) {
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
} from 'electron';
|
||||
import is from 'electron-is';
|
||||
|
||||
import config from './config';
|
||||
import * as config from './config';
|
||||
|
||||
import {
|
||||
forceLoadPreloadPlugin,
|
||||
|
||||
@ -2,7 +2,7 @@ import path from 'node:path';
|
||||
|
||||
import { app, BrowserWindow, ipcMain } from 'electron';
|
||||
|
||||
import config from '@/config';
|
||||
import * as config from '@/config';
|
||||
|
||||
export const restart = () => restartInternal();
|
||||
|
||||
|
||||
@ -2,5 +2,3 @@ export const getSongMenu = () =>
|
||||
document.querySelector<HTMLElement>(
|
||||
'ytmusic-menu-popup-renderer tp-yt-paper-listbox',
|
||||
);
|
||||
|
||||
export default { getSongMenu };
|
||||
|
||||
@ -2,7 +2,7 @@ import path from 'node:path';
|
||||
|
||||
import { app, type BrowserWindow } from 'electron';
|
||||
|
||||
import getSongControls from './song-controls';
|
||||
import { getSongControls } from './song-controls';
|
||||
|
||||
export const APP_PROTOCOL = 'youtubemusic';
|
||||
|
||||
@ -36,10 +36,3 @@ export function changeProtocolHandler(
|
||||
) {
|
||||
protocolHandler = f;
|
||||
}
|
||||
|
||||
export default {
|
||||
APP_PROTOCOL,
|
||||
setupProtocolHandler,
|
||||
handleProtocol,
|
||||
changeProtocolHandler,
|
||||
};
|
||||
|
||||
@ -36,7 +36,7 @@ const parseStringFromArgsType = (args: ArgsType<string>) => {
|
||||
}
|
||||
};
|
||||
|
||||
export default (win: BrowserWindow) => {
|
||||
export const getSongControls = (win: BrowserWindow) => {
|
||||
return {
|
||||
// Playback
|
||||
previous: () => win.webContents.send('ytmd:previous-video'),
|
||||
|
||||
@ -12,6 +12,8 @@ import type {
|
||||
import type { SongInfo } from './song-info';
|
||||
import type { VideoDataChanged } from '@/types/video-data-changed';
|
||||
|
||||
const DATAUPDATED_FALLBACK_TIMEOUT_MS = 1500;
|
||||
|
||||
let songInfo: SongInfo = {} as SongInfo;
|
||||
export const getSongInfo = () => songInfo;
|
||||
|
||||
@ -145,6 +147,7 @@ export const setupShuffleChangedListener = singleton(() => {
|
||||
|
||||
observer.observe(playerBar, {
|
||||
attributes: true,
|
||||
attributeFilter: ['shuffle-on'],
|
||||
childList: false,
|
||||
subtree: false,
|
||||
});
|
||||
@ -168,6 +171,7 @@ export const setupFullScreenChangedListener = singleton(() => {
|
||||
|
||||
observer.observe(playerBar, {
|
||||
attributes: true,
|
||||
attributeFilter: ['player-fullscreened'],
|
||||
childList: false,
|
||||
subtree: false,
|
||||
});
|
||||
@ -189,7 +193,7 @@ export const setupAutoPlayChangedListener = singleton(() => {
|
||||
});
|
||||
});
|
||||
|
||||
export default (api: YoutubePlayer) => {
|
||||
export const setupSongInfo = (api: YoutubePlayer) => {
|
||||
window.ipcRenderer.on('ytmd:setup-time-changed-listener', () => {
|
||||
setupTimeChangedListener();
|
||||
});
|
||||
@ -251,12 +255,25 @@ export default (api: YoutubePlayer) => {
|
||||
);
|
||||
|
||||
const waitingEvent = new Set<string>();
|
||||
const waitingTimeouts = new Map<string, NodeJS.Timeout>();
|
||||
|
||||
const clearVideoTimeout = (videoId: string) => {
|
||||
const timeoutId = waitingTimeouts.get(videoId);
|
||||
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
waitingTimeouts.delete(videoId);
|
||||
}
|
||||
};
|
||||
|
||||
// Name = "dataloaded" and abit later "dataupdated"
|
||||
// Sometimes "dataupdated" is not fired, so we need to fallback to "dataloaded"
|
||||
api.addEventListener('videodatachange', (name, videoData) => {
|
||||
videoEventDispatcher(name, videoData);
|
||||
|
||||
if (name === 'dataupdated' && waitingEvent.has(videoData.videoId)) {
|
||||
waitingEvent.delete(videoData.videoId);
|
||||
clearVideoTimeout(videoData.videoId);
|
||||
sendSongInfo(videoData);
|
||||
} else if (name === 'dataloaded') {
|
||||
const video = document.querySelector<HTMLVideoElement>('video');
|
||||
@ -267,7 +284,18 @@ export default (api: YoutubePlayer) => {
|
||||
video?.addEventListener(status, playPausedHandlers[status]);
|
||||
}
|
||||
|
||||
clearVideoTimeout(videoData.videoId);
|
||||
waitingEvent.add(videoData.videoId);
|
||||
|
||||
const timeoutId = setTimeout(() => {
|
||||
if (waitingEvent.has(videoData.videoId)) {
|
||||
waitingEvent.delete(videoData.videoId);
|
||||
waitingTimeouts.delete(videoData.videoId);
|
||||
sendSongInfo(videoData);
|
||||
}
|
||||
}, DATAUPDATED_FALLBACK_TIMEOUT_MS);
|
||||
|
||||
waitingTimeouts.set(videoData.videoId, timeoutId);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import { type BrowserWindow, ipcMain, nativeImage, net } from 'electron';
|
||||
|
||||
import { Mutex } from 'async-mutex';
|
||||
|
||||
import config from '@/config';
|
||||
import * as config from '@/config';
|
||||
|
||||
import type { GetPlayerResponse } from '@/types/get-player-response';
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import i18next from 'i18next';
|
||||
|
||||
import { startingPages } from './providers/extracted-data';
|
||||
import setupSongInfo from './providers/song-info-front';
|
||||
import { setupSongInfo } from './providers/song-info-front';
|
||||
import {
|
||||
createContext,
|
||||
forceLoadRendererPlugin,
|
||||
|
||||
2
src/reset.d.ts
vendored
2
src/reset.d.ts
vendored
@ -3,7 +3,7 @@ import '@total-typescript/ts-reset';
|
||||
import type { ipcRenderer as electronIpcRenderer } from 'electron';
|
||||
import type is from 'electron-is';
|
||||
|
||||
import type config from './config';
|
||||
import type * as config from './config';
|
||||
import type { VideoDataChanged } from '@/types/video-data-changed';
|
||||
import type { t } from '@/i18n';
|
||||
import type { trustedTypes } from 'trusted-types';
|
||||
|
||||
@ -4,11 +4,11 @@ import is from 'electron-is';
|
||||
import defaultTrayIconAsset from '@assets/youtube-music-tray.png?asset&asarUnpack';
|
||||
import pausedTrayIconAsset from '@assets/youtube-music-tray-paused.png?asset&asarUnpack';
|
||||
|
||||
import config from './config';
|
||||
import * as config from './config';
|
||||
|
||||
import { restart } from './providers/app-controls';
|
||||
import { registerCallback, SongInfoEvent } from './providers/song-info';
|
||||
import getSongControls from './providers/song-controls';
|
||||
import { getSongControls } from './providers/song-controls';
|
||||
|
||||
import { t } from '@/i18n';
|
||||
|
||||
|
||||
@ -1,3 +1 @@
|
||||
export const isTesting = () => process.env.NODE_ENV === 'test';
|
||||
|
||||
export default { isTesting };
|
||||
|
||||
4
src/yt-web-components.d.ts
vendored
4
src/yt-web-components.d.ts
vendored
@ -48,8 +48,8 @@ declare module 'solid-js' {
|
||||
'tp-yt-paper-icon-button': ComponentProps<'div'> &
|
||||
TpYtPaperIconButtonProps;
|
||||
'yt-icon-button': ComponentProps<'div'> & TpYtPaperIconButtonProps;
|
||||
'tp-yt-iron-icon': ComponentProps<'div'>;
|
||||
'yt-icon': ComponentProps<'div'>;
|
||||
'tp-yt-iron-icon': ComponentProps<'div'> & TpYtPaperIconButtonProps;
|
||||
'yt-icon': ComponentProps<'div'> & TpYtPaperIconButtonProps;
|
||||
// input type="range" slider component
|
||||
'tp-yt-paper-slider': ComponentProps<'input'> & {
|
||||
'value'?: number | string;
|
||||
|
||||
Reference in New Issue
Block a user