diff --git a/package.json b/package.json index 43fc654..4c383f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yesplamusic", - "productName": "YesPlayMusic", + "productName": "YesPlayMusic-alpha", "private": true, "version": "2.0.0", "description": "A nifty third-party NetEase Music player", diff --git a/packages/electron/.electron-builder.config.js b/packages/desktop/.electron-builder.config.js similarity index 94% rename from packages/electron/.electron-builder.config.js rename to packages/desktop/.electron-builder.config.js index d86f4ff..66bdb72 100644 --- a/packages/electron/.electron-builder.config.js +++ b/packages/desktop/.electron-builder.config.js @@ -3,9 +3,11 @@ * @see https://www.electron.build/configuration/configuration */ +const pkg = require('../../package.json') + module.exports = { - appId: 'com.qier222.yesplaymusic', - productName: 'YesPlayMusic', + appId: 'com.qier222.yesplaymusic.alpha', + productName: pkg.productName, copyright: 'Copyright © 2022 qier222', asar: false, directories: { @@ -99,7 +101,7 @@ module.exports = { }, files: [ '!**/*.ts', - '!**/node_modules/better-sqlite3/{bin,build,deps}/**', + // '!**/node_modules/better-sqlite3/{bin,build,deps}/**', '!**/node_modules/*/{*.MD,*.md,README,readme}', '!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}', '!**/node_modules/*.d.ts', diff --git a/packages/electron/assets/icons/taskbar/next.png b/packages/desktop/assets/icons/taskbar/next.png similarity index 100% rename from packages/electron/assets/icons/taskbar/next.png rename to packages/desktop/assets/icons/taskbar/next.png diff --git a/packages/electron/assets/icons/taskbar/pause.png b/packages/desktop/assets/icons/taskbar/pause.png similarity index 100% rename from packages/electron/assets/icons/taskbar/pause.png rename to packages/desktop/assets/icons/taskbar/pause.png diff --git a/packages/electron/assets/icons/taskbar/play.png b/packages/desktop/assets/icons/taskbar/play.png similarity index 100% rename from packages/electron/assets/icons/taskbar/play.png rename to packages/desktop/assets/icons/taskbar/play.png diff --git a/packages/electron/assets/icons/taskbar/previous.png b/packages/desktop/assets/icons/taskbar/previous.png similarity index 100% rename from packages/electron/assets/icons/taskbar/previous.png rename to packages/desktop/assets/icons/taskbar/previous.png diff --git a/packages/electron/assets/icons/tray/exit.png b/packages/desktop/assets/icons/tray/exit.png similarity index 100% rename from packages/electron/assets/icons/tray/exit.png rename to packages/desktop/assets/icons/tray/exit.png diff --git a/packages/electron/assets/icons/tray/left.png b/packages/desktop/assets/icons/tray/left.png similarity index 100% rename from packages/electron/assets/icons/tray/left.png rename to packages/desktop/assets/icons/tray/left.png diff --git a/packages/electron/assets/icons/tray/like.png b/packages/desktop/assets/icons/tray/like.png similarity index 100% rename from packages/electron/assets/icons/tray/like.png rename to packages/desktop/assets/icons/tray/like.png diff --git a/packages/electron/assets/icons/tray/menu.png b/packages/desktop/assets/icons/tray/menu.png similarity index 100% rename from packages/electron/assets/icons/tray/menu.png rename to packages/desktop/assets/icons/tray/menu.png diff --git a/packages/electron/assets/icons/tray/menu@88.png b/packages/desktop/assets/icons/tray/menu@88.png similarity index 100% rename from packages/electron/assets/icons/tray/menu@88.png rename to packages/desktop/assets/icons/tray/menu@88.png diff --git a/packages/electron/assets/icons/tray/pause.png b/packages/desktop/assets/icons/tray/pause.png similarity index 100% rename from packages/electron/assets/icons/tray/pause.png rename to packages/desktop/assets/icons/tray/pause.png diff --git a/packages/electron/assets/icons/tray/play.png b/packages/desktop/assets/icons/tray/play.png similarity index 100% rename from packages/electron/assets/icons/tray/play.png rename to packages/desktop/assets/icons/tray/play.png diff --git a/packages/electron/assets/icons/tray/repeat.png b/packages/desktop/assets/icons/tray/repeat.png similarity index 100% rename from packages/electron/assets/icons/tray/repeat.png rename to packages/desktop/assets/icons/tray/repeat.png diff --git a/packages/electron/assets/icons/tray/right.png b/packages/desktop/assets/icons/tray/right.png similarity index 100% rename from packages/electron/assets/icons/tray/right.png rename to packages/desktop/assets/icons/tray/right.png diff --git a/packages/electron/assets/icons/tray/unlike.png b/packages/desktop/assets/icons/tray/unlike.png similarity index 100% rename from packages/electron/assets/icons/tray/unlike.png rename to packages/desktop/assets/icons/tray/unlike.png diff --git a/packages/electron/build/icons/1024x1024.png b/packages/desktop/build/icons/1024x1024.png similarity index 100% rename from packages/electron/build/icons/1024x1024.png rename to packages/desktop/build/icons/1024x1024.png diff --git a/packages/electron/build/icons/128x128.png b/packages/desktop/build/icons/128x128.png similarity index 100% rename from packages/electron/build/icons/128x128.png rename to packages/desktop/build/icons/128x128.png diff --git a/packages/electron/build/icons/16x16.png b/packages/desktop/build/icons/16x16.png similarity index 100% rename from packages/electron/build/icons/16x16.png rename to packages/desktop/build/icons/16x16.png diff --git a/packages/electron/build/icons/24x24.png b/packages/desktop/build/icons/24x24.png similarity index 100% rename from packages/electron/build/icons/24x24.png rename to packages/desktop/build/icons/24x24.png diff --git a/packages/electron/build/icons/256x256.png b/packages/desktop/build/icons/256x256.png similarity index 100% rename from packages/electron/build/icons/256x256.png rename to packages/desktop/build/icons/256x256.png diff --git a/packages/electron/build/icons/32x32.png b/packages/desktop/build/icons/32x32.png similarity index 100% rename from packages/electron/build/icons/32x32.png rename to packages/desktop/build/icons/32x32.png diff --git a/packages/electron/build/icons/48x48.png b/packages/desktop/build/icons/48x48.png similarity index 100% rename from packages/electron/build/icons/48x48.png rename to packages/desktop/build/icons/48x48.png diff --git a/packages/electron/build/icons/512x512.png b/packages/desktop/build/icons/512x512.png similarity index 100% rename from packages/electron/build/icons/512x512.png rename to packages/desktop/build/icons/512x512.png diff --git a/packages/electron/build/icons/64x64.png b/packages/desktop/build/icons/64x64.png similarity index 100% rename from packages/electron/build/icons/64x64.png rename to packages/desktop/build/icons/64x64.png diff --git a/packages/electron/build/icons/icon.icns b/packages/desktop/build/icons/icon.icns similarity index 100% rename from packages/electron/build/icons/icon.icns rename to packages/desktop/build/icons/icon.icns diff --git a/packages/electron/build/icons/icon.ico b/packages/desktop/build/icons/icon.ico similarity index 100% rename from packages/electron/build/icons/icon.ico rename to packages/desktop/build/icons/icon.ico diff --git a/packages/electron/build/icons/icon.png b/packages/desktop/build/icons/icon.png similarity index 100% rename from packages/electron/build/icons/icon.png rename to packages/desktop/build/icons/icon.png diff --git a/packages/electron/build/icons/menu@88.png b/packages/desktop/build/icons/menu@88.png similarity index 100% rename from packages/electron/build/icons/menu@88.png rename to packages/desktop/build/icons/menu@88.png diff --git a/packages/desktop/main/airplay.ts b/packages/desktop/main/airplay.ts new file mode 100644 index 0000000..1855818 --- /dev/null +++ b/packages/desktop/main/airplay.ts @@ -0,0 +1,283 @@ +import { $ } from 'zx' +import store from './store' +import { ipcMain, BrowserWindow } from 'electron' +import { getNetworkInfo, sleep } from './utils' +import { spawn, ChildProcessWithoutNullStreams } from 'child_process' +import log from './log' + +type Protocol = 'dmap' | 'mrp' | 'airplay' | 'companion' | 'raop' +interface Device { + name: string + address: string + identifier: string + services: { protocol: Protocol; port: number }[] +} + +class Airplay { + devices: Device[] = [] + pairProcess: ChildProcessWithoutNullStreams | null = null + window: BrowserWindow + + constructor(window: BrowserWindow) { + log.debug('[airplay] ini') + this.window = window + this.initIpc() + } + + async checkIsInstalled() { + const help = (await $`atvscript -h`).toString() + return String(help).includes('usage: atvscript') + } + + async scanDevices(excludeThisDevice: boolean = true) { + if (!this.checkIsInstalled()) { + return { + result: 'failure', + error: 'pyatv is not installed', + } + } + + let scanResult = null + try { + scanResult = await $`atvscript scan` + } catch (p: any) { + return { + result: 'failure', + error: p.stderr, + } + } + + let json = null + try { + json = JSON.parse(scanResult.toString()) + } catch (e) { + return { + result: 'failure', + error: String(e), + } + } + + if (excludeThisDevice) { + const macAddress = getNetworkInfo()?.mac + if (macAddress) { + json.devices = json.devices.filter( + (device: Device) => + device.identifier.toLowerCase() !== macAddress.toLowerCase() + ) + } + } + + if (json.result === 'success') { + this.devices = json.devices + } + + return json + } + + async pairDevice(deviceID: string, protocol: Protocol) { + this.pairProcess = spawn('atvremote', [ + '--id', + deviceID, + '--protocol', + protocol, + 'pair', + ]) + + let paired = false + let done = false + this.pairProcess.stdout.on('data', (data: any) => { + console.log('stdout', String(data)) + if (data.includes('You may now use these credentials:')) { + store.set( + `airplay.credentials.${deviceID}`, + String(data).split('credentials:')[1].trim() + ) + paired = true + done = true + } + if (data.includes('Pairing failed')) { + paired = false + done = true + } + }) + + while (!done) { + console.log('not done yet') + await sleep(1000) + } + + return paired + } + + async enterPairPin(pin: string) { + if (!this.pairProcess) { + return false + } + this.pairProcess.stdin.write(`${pin}\n`) + return true + } + + async playUrl(deviceID: string, url: string) { + log.debug(`[airplay] playUrl ${url}`) + const credentials: string = store.get(`airplay.credentials.${deviceID}`) + if (url.includes('127.0.0.1')) { + const ip = getNetworkInfo()?.address + if (ip) url = url.replace('127.0.0.1', ip) + } + + try { + spawn('atvremote', [ + '--id', + deviceID, + '--airplay-credentials', + credentials, + `play_url=${url}`, + ]) + } catch (p: any) { + return { + result: 'failure', + error: p.stderr, + } + } + } + + async getPlaying(deviceID: string) { + if (!this.checkIsInstalled()) { + return { + result: 'failure', + error: 'pyatv is not installed', + } + } + + const credentials = store.get(`airplay.credentials.${deviceID}`) + + let playing = null + try { + playing = + await $`atvscript --id ${deviceID} --airplay-credentials=${credentials} playing` + } catch (p: any) { + return { + result: 'failure', + error: p.stderr, + } + } + + let json = null + try { + json = JSON.parse(playing.toString()) + } catch (e) { + return { + result: 'failure', + error: String(e), + } + } + + return json + } + + async play(deviceID: string) { + const credentials = store.get(`airplay.credentials.${deviceID}`) + try { + $`atvscript --id ${deviceID} --airplay-credentials ${credentials} play` + } catch (p: any) { + return { + result: 'failure', + error: p.stderr, + } + } + + return { + result: 'success', + } + } + + async pause(deviceID: string) { + const credentials = store.get(`airplay.credentials.${deviceID}`) + try { + $`atvscript --id ${deviceID} --airplay-credentials ${credentials} pause` + } catch (p: any) { + return { + result: 'failure', + error: p.stderr, + } + } + + return { + result: 'success', + } + } + + async playOrPause(deviceID: string) { + const credentials = store.get(`airplay.credentials.${deviceID}`) + try { + $`atvscript --id ${deviceID} --airplay-credentials ${credentials} play_pause` + } catch (p: any) { + return { + result: 'failure', + error: p.stderr, + } + } + + return { + result: 'success', + } + } + + async setProgress(deviceID: string, progress: number) { + const credentials = store.get(`airplay.credentials.${deviceID}`) + try { + $`atvremote --id ${deviceID} --airplay-credentials ${credentials} set_position=${progress}` + } catch (p: any) { + return { + result: 'failure', + error: p.stderr, + } + } + + return { + result: 'success', + } + } + + async pushUpdates(deviceID: string) { + const credentials = store.get(`airplay.credentials.${deviceID}`) + let updates = null + try { + updates = $`atvscript --id ${deviceID} --airplay-credentials ${credentials} push_updates` + } catch (p: any) { + return { + result: 'failure', + error: p.stderr, + } + } + + for await (const chunk of updates.stdout) { + this.window.webContents.send('airplay-updates', chunk) + } + } + + async initIpc() { + ipcMain.handle('airplay-scan-devices', () => { + return this.scanDevices() + }) + + ipcMain.handle('airplay-pair', async () => { + console.log('airplay-pair') + return this.pairDevice('58:D3:49:F0:C9:71', 'airplay') + }) + + ipcMain.handle('airplay-pair-enter-pin', async (e, pin) => { + return this.enterPairPin(pin) + }) + + ipcMain.handle('airplay-play-url', async (e, { deviceID, url }) => { + return this.playUrl(deviceID, url) + }) + + ipcMain.handle('airplay-get-playing', async (e, { deviceID }) => { + return this.getPlaying(deviceID) + }) + } +} + +export default Airplay diff --git a/packages/electron/main/appleMusic.ts b/packages/desktop/main/appleMusic.ts similarity index 94% rename from packages/electron/main/appleMusic.ts rename to packages/desktop/main/appleMusic.ts index 5199d09..a388a78 100644 --- a/packages/electron/main/appleMusic.ts +++ b/packages/desktop/main/appleMusic.ts @@ -41,13 +41,14 @@ export const getAlbum = async ({ log.debug('[appleMusic] Search album error', e) }) - const albums = searchResult?.data?.results?.albums?.data as AppleMusicAlbum[] + const albums: AppleMusicAlbum[] | undefined = + searchResult?.data?.results?.albums?.data const album = - albums.find( + albums?.find( a => a.attributes.name.toLowerCase() === name.toLowerCase() && a.attributes.artistName.toLowerCase() === artist.toLowerCase() - ) || albums[0] + ) || albums?.[0] if (!album) { log.debug('[appleMusic] No album found on apple music') return diff --git a/packages/electron/main/cache.ts b/packages/desktop/main/cache.ts similarity index 100% rename from packages/electron/main/cache.ts rename to packages/desktop/main/cache.ts diff --git a/packages/electron/main/db.ts b/packages/desktop/main/db.ts similarity index 100% rename from packages/electron/main/db.ts rename to packages/desktop/main/db.ts diff --git a/packages/electron/main/index.ts b/packages/desktop/main/index.ts similarity index 87% rename from packages/electron/main/index.ts rename to packages/desktop/main/index.ts index 5c073f4..de09f6f 100644 --- a/packages/electron/main/index.ts +++ b/packages/desktop/main/index.ts @@ -7,7 +7,6 @@ import { app, shell, } from 'electron' -import Store from 'electron-store' import { release } from 'os' import { join } from 'path' import log from './log' @@ -17,30 +16,13 @@ import { IpcChannels } from '@/shared/IpcChannels' import { createTaskbar, Thumbar } from './windowsTaskbar' import { createMenu } from './menu' import { isDev, isWindows, isLinux, isMac } from './utils' - -export interface TypedElectronStore { - window: { - width: number - height: number - x?: number - y?: number - } - // settings: State['settings'] -} +import store from './store' +import Airplay from './airplay' class Main { win: BrowserWindow | null = null tray: YPMTray | null = null thumbar: Thumbar | null = null - store = new Store({ - defaults: { - window: { - width: 1440, - height: 1024, - }, - // settings: initialState.settings, - }, - }) constructor() { log.info('[index] Main process start') @@ -63,10 +45,11 @@ class Main { this.handleAppEvents() this.handleWindowEvents() this.createTray() - createMenu(this.win!) + createMenu(this.win) this.createThumbar() - initIpcMain(this.win, this.tray, this.thumbar, this.store) + initIpcMain(this.win, this.tray, this.thumbar, store) this.initDevTools() + new Airplay(this.win) }) } @@ -102,8 +85,8 @@ class Main { webPreferences: { preload: join(__dirname, 'rendererPreload.js'), }, - width: this.store.get('window.width'), - height: this.store.get('window.height'), + width: store.get('window.width'), + height: store.get('window.height'), minWidth: 1240, minHeight: 848, titleBarStyle: isMac ? 'customButtonsOnHover' : 'hidden', @@ -111,9 +94,9 @@ class Main { frame: false, transparent: true, } - if (this.store.get('window')) { - options.x = this.store.get('window.x') - options.y = this.store.get('window.y') + if (store.get('window')) { + options.x = store.get('window.x') + options.y = store.get('window.y') } this.win = new BrowserWindow(options) @@ -186,11 +169,21 @@ class Main { this.win && this.win.webContents.send(IpcChannels.IsMaximized, false) }) + this.win.on('enter-full-screen', () => { + this.win && + this.win.webContents.send(IpcChannels.FullscreenStateChange, true) + }) + + this.win.on('leave-full-screen', () => { + this.win && + this.win.webContents.send(IpcChannels.FullscreenStateChange, false) + }) + // Save window position const saveBounds = () => { const bounds = this.win?.getBounds() if (bounds) { - this.store.set('window', bounds) + store.set('window', bounds) } } this.win.on('resized', saveBounds) diff --git a/packages/electron/main/ipcMain.ts b/packages/desktop/main/ipcMain.ts similarity index 97% rename from packages/electron/main/ipcMain.ts rename to packages/desktop/main/ipcMain.ts index 74a404d..355b0fa 100644 --- a/packages/electron/main/ipcMain.ts +++ b/packages/desktop/main/ipcMain.ts @@ -5,7 +5,7 @@ import cache from './cache' import log from './log' import fs from 'fs' import Store from 'electron-store' -import { TypedElectronStore } from './index' +import { TypedElectronStore } from './store' import { APIs } from '@/shared/CacheAPIs' import { YPMTray } from './tray' import { Thumbar } from './windowsTaskbar' @@ -66,6 +66,11 @@ function initWindowIpcMain(win: BrowserWindow | null) { if (!win) return win?.setSize(1440, 1024, true) }) + + on(IpcChannels.IsMaximized, e => { + if (!win) return + e.returnValue = win.isMaximized() + }) } /** diff --git a/packages/electron/main/log.ts b/packages/desktop/main/log.ts similarity index 100% rename from packages/electron/main/log.ts rename to packages/desktop/main/log.ts diff --git a/packages/electron/main/menu.ts b/packages/desktop/main/menu.ts similarity index 83% rename from packages/electron/main/menu.ts rename to packages/desktop/main/menu.ts index e9ed881..121904f 100644 --- a/packages/electron/main/menu.ts +++ b/packages/desktop/main/menu.ts @@ -1,4 +1,5 @@ import { + app, BrowserWindow, Menu, MenuItem, @@ -28,6 +29,18 @@ export const createMenu = (win: BrowserWindow) => { } }, }, + { + label: '打开应用数据目录', + click: async () => { + const path = app.getPath('userData') + if (isMac) { + exec(`open ${path}`) + } else { + // TODO: 测试Windows和Linux是否能正确打开日志目录 + shell.openPath(path) + } + }, + }, { label: '打开开发者工具', click: async () => { diff --git a/packages/electron/main/preload.ts b/packages/desktop/main/preload.ts similarity index 100% rename from packages/electron/main/preload.ts rename to packages/desktop/main/preload.ts diff --git a/packages/electron/main/rendererPreload.ts b/packages/desktop/main/rendererPreload.ts similarity index 100% rename from packages/electron/main/rendererPreload.ts rename to packages/desktop/main/rendererPreload.ts diff --git a/packages/electron/main/sentry.ts b/packages/desktop/main/sentry.ts similarity index 86% rename from packages/electron/main/sentry.ts rename to packages/desktop/main/sentry.ts index ed32894..61f6685 100644 --- a/packages/electron/main/sentry.ts +++ b/packages/desktop/main/sentry.ts @@ -1,5 +1,4 @@ -import * as Sentry from '@sentry/node' -import * as Tracing from '@sentry/tracing' +import * as Sentry from '@sentry/electron' import pkg from '../../../package.json' import log from './log' diff --git a/packages/electron/main/server.ts b/packages/desktop/main/server.ts similarity index 97% rename from packages/electron/main/server.ts rename to packages/desktop/main/server.ts index 9c6d476..790aeea 100644 --- a/packages/electron/main/server.ts +++ b/packages/desktop/main/server.ts @@ -13,6 +13,7 @@ import UNM from '@unblockneteasemusic/rust-napi' import { APIs as CacheAPIs } from '@/shared/CacheAPIs' import { isProd } from './utils' import { APIs } from '@/shared/CacheAPIs' +import history from 'connect-history-api-fallback' class Server { port = Number( @@ -77,7 +78,8 @@ class Server { serveStaticForProduction() { if (isProd) { - this.app.use('/', express.static(path.join(__dirname, '../web/'))) + this.app.use(history()) + this.app.use(express.static(path.join(__dirname, '../web'))) } } @@ -274,7 +276,7 @@ class Server { return } } catch (error) { - log.error(`[server] getFromNetease failed: ${String(error)}`) + log.error(`[server] getFromUNM failed: ${String(error)}`) } if (fromNetease?.data?.[0].freeTrialInfo) { @@ -331,7 +333,7 @@ class Server { } listen() { - this.app.listen(this.port, () => { + this.app.listen(this.port, '0.0.0.0', () => { log.info(`[server] API server listening on port ${this.port}`) }) } diff --git a/packages/desktop/main/store.ts b/packages/desktop/main/store.ts new file mode 100644 index 0000000..5b27c25 --- /dev/null +++ b/packages/desktop/main/store.ts @@ -0,0 +1,31 @@ +import Store from 'electron-store' + +export interface TypedElectronStore { + window: { + width: number + height: number + x?: number + y?: number + } + // settings: State['settings'] + airplay: { + credentials: { + [key: string]: string + } + } +} + +const store = new Store({ + defaults: { + window: { + width: 1440, + height: 1024, + }, + // settings: initialState.settings, + airplay: { + credentials: {}, + }, + }, +}) + +export default store diff --git a/packages/electron/main/tray.ts b/packages/desktop/main/tray.ts similarity index 100% rename from packages/electron/main/tray.ts rename to packages/desktop/main/tray.ts diff --git a/packages/electron/main/utils.ts b/packages/desktop/main/utils.ts similarity index 85% rename from packages/electron/main/utils.ts rename to packages/desktop/main/utils.ts index cee189c..cabfc13 100644 --- a/packages/electron/main/utils.ts +++ b/packages/desktop/main/utils.ts @@ -1,5 +1,6 @@ import fs from 'fs' import path from 'path' +import os from 'os' import pkg from '../../../package.json' export const isDev = process.env.NODE_ENV === 'development' @@ -31,3 +32,9 @@ export const createFileIfNotExist = (file: string) => { fs.writeFileSync(file, '') } } + +export const getNetworkInfo = () => { + return os.networkInterfaces().en0?.find(n => n.family === 'IPv4') +} + +export const sleep = (ms: number) => new Promise(r => setTimeout(r, ms)) diff --git a/packages/electron/main/windowsTaskbar.ts b/packages/desktop/main/windowsTaskbar.ts similarity index 100% rename from packages/electron/main/windowsTaskbar.ts rename to packages/desktop/main/windowsTaskbar.ts diff --git a/packages/electron/migrations/init.sql b/packages/desktop/migrations/init.sql similarity index 91% rename from packages/electron/migrations/init.sql rename to packages/desktop/migrations/init.sql index 9f1d908..83763e9 100644 --- a/packages/electron/migrations/init.sql +++ b/packages/desktop/migrations/init.sql @@ -8,6 +8,6 @@ CREATE TABLE IF NOT EXISTS "Track" ("id" integer NOT NULL,"json" text NOT NULL," CREATE TABLE IF NOT EXISTS "AppData" ("id" text NOT NULL,"value" text, PRIMARY KEY (id)); CREATE TABLE IF NOT EXISTS "CoverColor" ("id" integer NOT NULL,"color" text NOT NULL, "queriedAt" int NOT NULL, PRIMARY KEY (id)); -CREATE TABLE IF NOT EXISTS "Audio" ("id" integer NOT NULL,"br" int NOT NULL,"type" text NOT NULL,"source" text NOT NULL,"updatedAt" int NOT NULL, "queriedAt" int NOT NULL, PRIMARY KEY (id)); +CREATE TABLE IF NOT EXISTS "Audio" ("id" integer NOT NULL,"br" int NOT NULL,"type" text NOT NULL,"source" text NOT NULL, "queriedAt" int NOT NULL, PRIMARY KEY (id)); CREATE TABLE IF NOT EXISTS "AppleMusicArtist" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id)); CREATE TABLE IF NOT EXISTS "AppleMusicAlbum" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id)); diff --git a/packages/electron/package.json b/packages/desktop/package.json similarity index 62% rename from packages/electron/package.json rename to packages/desktop/package.json index 0d52d34..934cf99 100644 --- a/packages/electron/package.json +++ b/packages/desktop/package.json @@ -1,5 +1,6 @@ { - "name": "electron", + "name": "desktop", + "productName": "YesPlayMusic-alpha", "private": true, "version": "2.0.0", "main": "./main/index.js", @@ -11,26 +12,31 @@ "pack": "electron-builder build -c .electron-builder.config.js", "test:types": "tsc --noEmit --project ./tsconfig.json", "lint": "eslint --ext .ts,.js ./", - "format": "prettier --write './**/*.{ts,js,tsx,jsx}'" + "format": "prettier --write './**/*.{ts,js,tsx,jsx}'", + "test": "vitest", + "test:ui": "vitest --ui", + "test:coverage": "vitest run --coverage" }, "engines": { "node": "^14.13.1 || >=16.0.0" }, "dependencies": { - "@sentry/node": "^6.19.7", - "@sentry/tracing": "^6.19.7", + "@sentry/electron": "^3.0.7", "@unblockneteasemusic/rust-napi": "^0.3.0", - "NeteaseCloudMusicApi": "^4.6.2", + "NeteaseCloudMusicApi": "^4.6.7", "better-sqlite3": "7.5.1", "change-case": "^4.1.2", + "chromecast-api": "^0.4.0", "compare-versions": "^4.1.3", + "connect-history-api-fallback": "^2.0.0", "cookie-parser": "^1.4.6", - "electron-log": "^4.4.6", - "electron-store": "^8.0.1", + "electron-log": "^4.4.8", + "electron-store": "^8.0.2", "express": "^4.18.1", "fast-folder-size": "^1.7.0", "m3u8-parser": "^4.7.1", - "pretty-bytes": "^6.0.0" + "pretty-bytes": "^6.0.0", + "zx": "^7.0.7" }, "devDependencies": { "@electron/universal": "1.2.1", @@ -38,27 +44,29 @@ "@types/cookie-parser": "^1.4.3", "@types/express": "^4.17.13", "@types/express-fileupload": "^1.2.2", - "@typescript-eslint/eslint-plugin": "^5.27.0", - "@typescript-eslint/parser": "^5.27.0", + "@typescript-eslint/eslint-plugin": "^5.30.7", + "@typescript-eslint/parser": "^5.30.7", "@vitejs/plugin-react": "^1.3.1", + "@vitest/ui": "^0.12.10", "axios": "^0.27.2", "cross-env": "^7.0.3", "dotenv": "^16.0.0", - "electron": "^19.0.3", - "electron-builder": "^23.0.3", + "electron": "^19.0.8", + "electron-builder": "23.3.1", "electron-devtools-installer": "^3.2.0", - "electron-rebuild": "^3.2.7", - "electron-releases": "^3.1026.0", - "esbuild": "^0.14.42", + "electron-rebuild": "^3.2.8", + "electron-releases": "^3.1072.0", + "esbuild": "^0.14.49", "eslint": "*", "express-fileupload": "^1.4.0", "minimist": "^1.2.6", - "music-metadata": "^7.12.3", + "music-metadata": "^7.12.4", "open-cli": "^7.0.1", - "ora": "^6.1.0", + "ora": "^6.1.2", "picocolors": "^1.0.0", "prettier": "*", "typescript": "*", + "vitest": "^0.12.10", "wait-on": "^6.0.1" }, "resolutions": { diff --git a/packages/electron/scripts/build.main.mjs b/packages/desktop/scripts/build.main.mjs similarity index 100% rename from packages/electron/scripts/build.main.mjs rename to packages/desktop/scripts/build.main.mjs diff --git a/packages/electron/scripts/build.sqlite3.js b/packages/desktop/scripts/build.sqlite3.js similarity index 92% rename from packages/electron/scripts/build.sqlite3.js rename to packages/desktop/scripts/build.sqlite3.js index 228d347..996e728 100644 --- a/packages/electron/scripts/build.sqlite3.js +++ b/packages/desktop/scripts/build.sqlite3.js @@ -25,8 +25,8 @@ const argv = minimist(process.argv.slice(2)) const projectDir = path.resolve(process.cwd(), '../../') -if (!fs.existsSync(`${projectDir}/packages/electron/dist/binary`)) { - fs.mkdirSync(`${projectDir}/packages/electron/dist/binary`, { +if (!fs.existsSync(`${projectDir}/packages/desktop/dist/binary`)) { + fs.mkdirSync(`${projectDir}/packages/desktop/dist/binary`, { recursive: true, }) } @@ -71,7 +71,7 @@ const download = async arch => { try { fs.copyFileSync( `${dir}/build/Release/better_sqlite3.node`, - `${projectDir}/packages/electron/dist/binary/better_sqlite3_${arch}.node` + `${projectDir}/packages/desktop/dist/binary/better_sqlite3_${arch}.node` ) } catch (e) { console.log(pc.red('Copy failed! Skip copy.', e)) @@ -105,7 +105,7 @@ const build = async arch => { console.info('Build succeeded') fs.copyFileSync( `${projectDir}/node_modules/better-sqlite3/build/Release/better_sqlite3.node`, - `${projectDir}/packages/electron/dist/binary/better_sqlite3_${arch}.node` + `${projectDir}/packages/desktop/dist/binary/better_sqlite3_${arch}.node` ) }) .catch(e => { diff --git a/packages/desktop/test/airplay.test.ts b/packages/desktop/test/airplay.test.ts new file mode 100644 index 0000000..efa416a --- /dev/null +++ b/packages/desktop/test/airplay.test.ts @@ -0,0 +1,10 @@ +import { expect, test, describe, vi } from 'vitest' +import { pairDevice, scanDevices } from '../main/airplay' + +// test('scanDevices', async () => { +// console.log(await scanDevices()) +// }, 10000000) + +// test('pairDevice', async () => { +// console.log(await pairDevice('58:D3:49:F0:C9:71', 'airplay')) +// }, 100000) diff --git a/packages/electron/tsconfig.json b/packages/desktop/tsconfig.json similarity index 89% rename from packages/electron/tsconfig.json rename to packages/desktop/tsconfig.json index d3b90a0..aff9074 100644 --- a/packages/electron/tsconfig.json +++ b/packages/desktop/tsconfig.json @@ -10,9 +10,9 @@ "resolveJsonModule": true, "strict": true, "jsx": "react-jsx", - "baseUrl": "./", + "baseUrl": "../", "paths": { - "@/*": ["../*"] + "@/*": ["./*"] } }, "include": ["./**/*.ts", "../shared/**/*.ts"] diff --git a/packages/shared/IpcChannels.ts b/packages/shared/IpcChannels.ts index 869a58b..ac817ad 100644 --- a/packages/shared/IpcChannels.ts +++ b/packages/shared/IpcChannels.ts @@ -8,6 +8,7 @@ export const enum IpcChannels { MaximizeOrUnmaximize = 'MaximizeOrUnmaximize', Close = 'Close', IsMaximized = 'IsMaximized', + FullscreenStateChange = 'FullscreenStateChange', GetApiCacheSync = 'GetApiCacheSync', DevDbExportJson = 'DevDbExportJson', CacheCoverColor = 'CacheCoverColor', @@ -34,6 +35,7 @@ export interface IpcChannelsParams { [IpcChannels.MaximizeOrUnmaximize]: void [IpcChannels.Close]: void [IpcChannels.IsMaximized]: void + [IpcChannels.FullscreenStateChange]: void [IpcChannels.GetApiCacheSync]: { api: APIs query?: any @@ -75,6 +77,7 @@ export interface IpcChannelsReturns { [IpcChannels.MaximizeOrUnmaximize]: void [IpcChannels.Close]: void [IpcChannels.IsMaximized]: boolean + [IpcChannels.FullscreenStateChange]: boolean [IpcChannels.GetApiCacheSync]: any [IpcChannels.DevDbExportJson]: void [IpcChannels.CacheCoverColor]: void diff --git a/packages/shared/api/Artist.ts b/packages/shared/api/Artist.ts index 2fd75b2..bf74ead 100644 --- a/packages/shared/api/Artist.ts +++ b/packages/shared/api/Artist.ts @@ -2,6 +2,7 @@ export enum ArtistApiNames { FetchArtist = 'fetchArtist', FetchArtistAlbums = 'fetchArtistAlbums', FetchSimilarArtists = 'fetchSimilarArtists', + FetchArtistMV = 'fetchArtistMV', } // 歌手详情 @@ -36,3 +37,39 @@ export interface FetchSimilarArtistsResponse { code: number artists: Artist[] } + +// 获取歌手MV +export interface FetchArtistMVParams { + id: number + offset?: number + limit?: number +} +export interface FetchArtistMVResponse { + code: number + hasMore: boolean + time: number + mvs: { + artist: Artist + artistName: string + duration: number + id: number + imgurl: string + imgurl16v9: string + name: string + playCount: number + publishTime: string + status: number + subed: boolean + }[] +} + +// 收藏歌手 +export interface LikeAArtistParams { + id: number + like: boolean +} +export interface LikeAArtistResponse { + code: number + data: null + message: string +} diff --git a/packages/shared/api/MV.ts b/packages/shared/api/MV.ts new file mode 100644 index 0000000..96a53ea --- /dev/null +++ b/packages/shared/api/MV.ts @@ -0,0 +1,80 @@ +export enum MVApiNames { + FetchMV = 'fetchMV', + FetchMVUrl = 'fetchMVUrl', +} + +// MV详情 +export interface FetchMVParams { + mvid: number +} +export interface FetchMVResponse { + code: number + loadingPic: string + bufferPic: string + loadingPicFS: string + bufferPicFS: string + data: { + artistId: number + artistName: string + artists: Artist[] + briefDesc: string + brs: { + br: number + point: number + size: number + }[] + commentCount: number + commentThreadId: string + cover: string + coverId: number + coverId_str: string + desc: string + duration: number + id: number + nType: number + name: string + playCount: number + price: null | unknown + publishTime: string + shareCount: number + subCount: number + videoGroup: unknown[] + } + mp: { + cp: number + dl: number + fee: number + id: number + msg: null | string + mvFee: number + normal: boolean + payed: number + pl: number + sid: number + st: number + unauthorized: boolean + } +} + +// MV地址 +export interface FetchMVUrlParams { + id: number + r?: number +} +export interface FetchMVUrlResponse { + code: number + data: { + code: number + expi: number + fee: number + id: number + md5: string + msg: string + mvFee: number + promotionVo: null | unknown + r: number + size: number + st: number + url: string + } +} diff --git a/packages/shared/api/User.ts b/packages/shared/api/User.ts index ad3c29c..6a66be3 100644 --- a/packages/shared/api/User.ts +++ b/packages/shared/api/User.ts @@ -3,7 +3,7 @@ export enum UserApiNames { FetchUserLikedTracksIds = 'fetchUserLikedTracksIDs', FetchUserPlaylists = 'fetchUserPlaylists', FetchUserAlbums = 'fetchUserAlbums', - FetchUserArtist = 'fetchUserArtists', + FetchUserArtists = 'fetchUserArtists', FetchListenedRecords = 'fetchListenedRecords', } diff --git a/packages/web/App.tsx b/packages/web/App.tsx index 8f5c6f4..72d16e9 100644 --- a/packages/web/App.tsx +++ b/packages/web/App.tsx @@ -1,5 +1,5 @@ import { Toaster } from 'react-hot-toast' -import { QueryClientProvider } from 'react-query' +import { QueryClientProvider } from '@tanstack/react-query' import { ReactQueryDevtools } from 'react-query/devtools' import Player from '@/web/components/Player' import Sidebar from '@/web/components/Sidebar' diff --git a/packages/web/api/album.ts b/packages/web/api/album.ts index d02e051..35f1ab6 100644 --- a/packages/web/api/album.ts +++ b/packages/web/api/album.ts @@ -8,15 +8,15 @@ import { // 专辑详情 export function fetchAlbum( - params: FetchAlbumParams, - noCache: boolean + params: FetchAlbumParams ): Promise { - const otherParams: { timestamp?: number } = {} - if (noCache) otherParams.timestamp = new Date().getTime() return request({ url: '/album', method: 'get', - params: { ...params, ...otherParams }, + params: { + ...params, + timestamp: new Date().getTime(), + }, }) } diff --git a/packages/web/api/artist.ts b/packages/web/api/artist.ts index 6ee5919..27b2ab2 100644 --- a/packages/web/api/artist.ts +++ b/packages/web/api/artist.ts @@ -6,19 +6,20 @@ import { FetchArtistAlbumsResponse, FetchSimilarArtistsParams, FetchSimilarArtistsResponse, + FetchArtistMVParams, + FetchArtistMVResponse, + LikeAArtistParams, + LikeAArtistResponse, } from '@/shared/api/Artist' // 歌手详情 export function fetchArtist( - params: FetchArtistParams, - noCache: boolean + params: FetchArtistParams ): Promise { - const otherParams: { timestamp?: number } = {} - if (noCache) otherParams.timestamp = new Date().getTime() return request({ url: '/artists', method: 'get', - params: { ...params, ...otherParams }, + params: { ...params, timestamp: new Date().getTime() }, }) } @@ -33,6 +34,7 @@ export function fetchArtistAlbums( }) } +// 获取相似歌手 export function fetchSimilarArtists( params: FetchSimilarArtistsParams ): Promise { @@ -42,3 +44,28 @@ export function fetchSimilarArtists( params, }) } + +// 获取歌手MV +export function fetchArtistMV( + params: FetchArtistMVParams +): Promise { + return request({ + url: '/artist/mv', + method: 'get', + params, + }) +} + +// 收藏歌手 +export function likeAArtist( + params: LikeAArtistParams +): Promise { + return request({ + url: 'artist/sub', + method: 'get', + params: { + id: params.id, + t: Number(params.like), + }, + }) +} diff --git a/packages/web/api/auth.ts b/packages/web/api/auth.ts index 4b3d5f5..1829453 100644 --- a/packages/web/api/auth.ts +++ b/packages/web/api/auth.ts @@ -30,7 +30,7 @@ export interface LoginWithEmailParams { password?: string md5_password?: string } -export interface loginWithEmailResponse extends FetchUserAccountResponse { +export interface LoginWithEmailResponse extends FetchUserAccountResponse { code: number cookie: string loginType: number @@ -49,7 +49,7 @@ export interface loginWithEmailResponse extends FetchUserAccountResponse { } export function loginWithEmail( params: LoginWithEmailParams -): Promise { +): Promise { return request({ url: '/login', method: 'post', @@ -58,14 +58,14 @@ export function loginWithEmail( } // 生成二维码key -export interface fetchLoginQrCodeKeyResponse { +export interface FetchLoginQrCodeKeyResponse { code: number data: { code: number unikey: string } } -export function fetchLoginQrCodeKey(): Promise { +export function fetchLoginQrCodeKey(): Promise { return request({ url: '/login/qr/key', method: 'get', diff --git a/packages/web/api/hooks/useAlbum.ts b/packages/web/api/hooks/useAlbum.ts index cfddf59..f5cee98 100644 --- a/packages/web/api/hooks/useAlbum.ts +++ b/packages/web/api/hooks/useAlbum.ts @@ -7,37 +7,33 @@ import { AlbumApiNames, FetchAlbumResponse, } from '@/shared/api/Album' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' -const fetch = async (params: FetchAlbumParams, noCache?: boolean) => { - const album = await fetchAlbum(params, !!noCache) +const fetch = async (params: FetchAlbumParams) => { + const album = await fetchAlbum(params) if (album?.album?.songs) { album.album.songs = album.songs } return album } -const fetchFromCache = (id: number): FetchAlbumResponse => +const fetchFromCache = (params: FetchAlbumParams): FetchAlbumResponse => window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, { api: APIs.Album, - query: { id }, + query: params, }) -export default function useAlbum(params: FetchAlbumParams, noCache?: boolean) { - return useQuery( - [AlbumApiNames.FetchAlbum, params.id], - () => fetch(params, noCache), - { - enabled: !!params.id, - staleTime: 24 * 60 * 60 * 1000, // 24 hours - placeholderData: () => fetchFromCache(params.id), - } - ) +export default function useAlbum(params: FetchAlbumParams) { + return useQuery([AlbumApiNames.FetchAlbum, params], () => fetch(params), { + enabled: !!params.id, + staleTime: 24 * 60 * 60 * 1000, // 24 hours + placeholderData: () => fetchFromCache(params), + }) } export function fetchAlbumWithReactQuery(params: FetchAlbumParams) { return reactQueryClient.fetchQuery( - [AlbumApiNames.FetchAlbum, params.id], + [AlbumApiNames.FetchAlbum, params], () => fetch(params), { staleTime: Infinity, @@ -46,9 +42,9 @@ export function fetchAlbumWithReactQuery(params: FetchAlbumParams) { } export async function prefetchAlbum(params: FetchAlbumParams) { - if (fetchFromCache(params.id)) return + if (fetchFromCache(params)) return await reactQueryClient.prefetchQuery( - [AlbumApiNames.FetchAlbum, params.id], + [AlbumApiNames.FetchAlbum, params], () => fetch(params), { staleTime: Infinity, diff --git a/packages/web/api/hooks/useArtist.ts b/packages/web/api/hooks/useArtist.ts index 1023447..f43db44 100644 --- a/packages/web/api/hooks/useArtist.ts +++ b/packages/web/api/hooks/useArtist.ts @@ -6,25 +6,46 @@ import { ArtistApiNames, FetchArtistResponse, } from '@/shared/api/Artist' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' +import reactQueryClient from '@/web/utils/reactQueryClient' -export default function useArtist( - params: FetchArtistParams, - noCache?: boolean -) { +const fetchFromCache = (id: number): FetchArtistResponse => + window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, { + api: APIs.Artist, + query: { + id, + }, + }) + +export default function useArtist(params: FetchArtistParams) { return useQuery( [ArtistApiNames.FetchArtist, params], - () => fetchArtist(params, !!noCache), + () => fetchArtist(params), { enabled: !!params.id && params.id > 0 && !isNaN(Number(params.id)), staleTime: 5 * 60 * 1000, // 5 mins - placeholderData: (): FetchArtistResponse => - window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, { - api: APIs.Artist, - query: { - id: params.id, - }, - }), + placeholderData: () => fetchFromCache(params.id), + } + ) +} + +export function fetchArtistWithReactQuery(params: FetchArtistParams) { + return reactQueryClient.fetchQuery( + [ArtistApiNames.FetchArtist, params], + () => fetchArtist(params), + { + staleTime: Infinity, + } + ) +} + +export async function prefetchArtist(params: FetchArtistParams) { + if (fetchFromCache(params.id)) return + await reactQueryClient.prefetchQuery( + [ArtistApiNames.FetchArtist, params], + () => fetchArtist(params), + { + staleTime: Infinity, } ) } diff --git a/packages/web/api/hooks/useArtistAlbums.ts b/packages/web/api/hooks/useArtistAlbums.ts index 34b3a3e..4ad15bf 100644 --- a/packages/web/api/hooks/useArtistAlbums.ts +++ b/packages/web/api/hooks/useArtistAlbums.ts @@ -6,9 +6,9 @@ import { ArtistApiNames, FetchArtistAlbumsResponse, } from '@/shared/api/Artist' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' -export default function useUserAlbums(params: FetchArtistAlbumsParams) { +export default function useArtistAlbums(params: FetchArtistAlbumsParams) { return useQuery( [ArtistApiNames.FetchArtistAlbums, params], async () => { diff --git a/packages/web/api/hooks/useArtistMV.ts b/packages/web/api/hooks/useArtistMV.ts new file mode 100644 index 0000000..cfcaf36 --- /dev/null +++ b/packages/web/api/hooks/useArtistMV.ts @@ -0,0 +1,30 @@ +import { fetchArtistMV } from '@/web/api/artist' +import { IpcChannels } from '@/shared/IpcChannels' +import { APIs } from '@/shared/CacheAPIs' +import { + FetchArtistMVParams, + ArtistApiNames, + FetchArtistMVResponse, +} from '@/shared/api/Artist' +import { useQuery } from '@tanstack/react-query' + +export default function useArtistMV(params: FetchArtistMVParams) { + return useQuery( + [ArtistApiNames.FetchArtistMV, params], + async () => { + const data = await fetchArtistMV(params) + return data + }, + { + enabled: !!params.id && params.id !== 0, + staleTime: 3600000, + // placeholderData: (): FetchArtistMVResponse => + // window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, { + // api: APIs.ArtistAlbum, + // query: { + // id: params.id, + // }, + // }), + } + ) +} diff --git a/packages/web/api/hooks/useArtists.ts b/packages/web/api/hooks/useArtists.ts index f3b5c1f..c9fed10 100644 --- a/packages/web/api/hooks/useArtists.ts +++ b/packages/web/api/hooks/useArtists.ts @@ -6,7 +6,7 @@ import { ArtistApiNames, FetchArtistResponse, } from '@/shared/api/Artist' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' export default function useArtists(ids: number[]) { return useQuery( diff --git a/packages/web/api/hooks/useLyric.ts b/packages/web/api/hooks/useLyric.ts index 9092065..792b853 100644 --- a/packages/web/api/hooks/useLyric.ts +++ b/packages/web/api/hooks/useLyric.ts @@ -7,7 +7,7 @@ import { } from '@/shared/api/Track' import { APIs } from '@/shared/CacheAPIs' import { IpcChannels } from '@/shared/IpcChannels' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' export default function useLyric(params: FetchLyricParams) { return useQuery( diff --git a/packages/web/api/hooks/useMV.ts b/packages/web/api/hooks/useMV.ts new file mode 100644 index 0000000..44612f0 --- /dev/null +++ b/packages/web/api/hooks/useMV.ts @@ -0,0 +1,31 @@ +import { fetchMV, fetchMVUrl } from '@/web/api/mv' +import { IpcChannels } from '@/shared/IpcChannels' +import { APIs } from '@/shared/CacheAPIs' +import { + MVApiNames, + FetchMVParams, + FetchMVResponse, + FetchMVUrlParams, +} from '@/shared/api/MV' +import { useQuery } from '@tanstack/react-query' + +export default function useMV(params: FetchMVParams) { + return useQuery([MVApiNames.FetchMV, params], () => fetchMV(params), { + enabled: !!params.mvid && params.mvid > 0 && !isNaN(Number(params.mvid)), + staleTime: 5 * 60 * 1000, // 5 mins + // placeholderData: (): FetchMVResponse => + // window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, { + // api: APIs.SimilarArtist, + // query: { + // id: params.id, + // }, + // }), + }) +} + +export function useMVUrl(params: FetchMVUrlParams) { + return useQuery([MVApiNames.FetchMVUrl, params], () => fetchMVUrl(params), { + enabled: !!params.id && params.id > 0 && !isNaN(Number(params.id)), + staleTime: 60 * 60 * 1000, // 60 mins + }) +} diff --git a/packages/web/api/hooks/usePersonalFM.ts b/packages/web/api/hooks/usePersonalFM.ts index 7423b75..aa37d5c 100644 --- a/packages/web/api/hooks/usePersonalFM.ts +++ b/packages/web/api/hooks/usePersonalFM.ts @@ -3,7 +3,7 @@ import reactQueryClient from '@/web/utils/reactQueryClient' export function fetchPersonalFMWithReactQuery() { return reactQueryClient.fetchQuery( - PersonalFMApiNames.FetchPersonalFm, + [PersonalFMApiNames.FetchPersonalFm], async () => { const data = await fetchPersonalFM() if (!data.data?.length) { diff --git a/packages/web/api/hooks/usePlaylist.ts b/packages/web/api/hooks/usePlaylist.ts index 91cf025..ce39bb2 100644 --- a/packages/web/api/hooks/usePlaylist.ts +++ b/packages/web/api/hooks/usePlaylist.ts @@ -7,10 +7,10 @@ import { PlaylistApiNames, FetchPlaylistResponse, } from '@/shared/api/Playlists' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' -const fetch = (params: FetchPlaylistParams, noCache?: boolean) => { - return fetchPlaylist(params, !!noCache) +const fetch = (params: FetchPlaylistParams) => { + return fetchPlaylist(params) } export const fetchFromCache = (id: number): FetchPlaylistResponse | undefined => @@ -19,13 +19,10 @@ export const fetchFromCache = (id: number): FetchPlaylistResponse | undefined => query: { id }, }) -export default function usePlaylist( - params: FetchPlaylistParams, - noCache?: boolean -) { +export default function usePlaylist(params: FetchPlaylistParams) { return useQuery( [PlaylistApiNames.FetchPlaylist, params], - () => fetch(params, noCache), + () => fetch(params), { enabled: !!(params.id && params.id > 0 && !isNaN(Number(params.id))), refetchOnWindowFocus: true, diff --git a/packages/web/api/hooks/useSimilarArtists.ts b/packages/web/api/hooks/useSimilarArtists.ts index 9878fa3..d579259 100644 --- a/packages/web/api/hooks/useSimilarArtists.ts +++ b/packages/web/api/hooks/useSimilarArtists.ts @@ -6,7 +6,7 @@ import { ArtistApiNames, FetchSimilarArtistsResponse, } from '@/shared/api/Artist' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' export default function useSimilarArtists(params: FetchSimilarArtistsParams) { return useQuery( @@ -15,6 +15,7 @@ export default function useSimilarArtists(params: FetchSimilarArtistsParams) { { enabled: !!params.id && params.id > 0 && !isNaN(Number(params.id)), staleTime: 5 * 60 * 1000, // 5 mins + retry: 0, placeholderData: (): FetchSimilarArtistsResponse => window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, { api: APIs.SimilarArtist, diff --git a/packages/web/api/hooks/useTracks.ts b/packages/web/api/hooks/useTracks.ts index 4cf9504..0df83bb 100644 --- a/packages/web/api/hooks/useTracks.ts +++ b/packages/web/api/hooks/useTracks.ts @@ -9,7 +9,7 @@ import { TrackApiNames, } from '@/shared/api/Track' import { APIs } from '@/shared/CacheAPIs' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' export default function useTracks(params: FetchTracksParams) { return useQuery( diff --git a/packages/web/api/hooks/useTracksInfinite.ts b/packages/web/api/hooks/useTracksInfinite.ts index 40e5b56..edd3bce 100644 --- a/packages/web/api/hooks/useTracksInfinite.ts +++ b/packages/web/api/hooks/useTracksInfinite.ts @@ -1,5 +1,5 @@ import { FetchTracksParams, TrackApiNames } from '@/shared/api/Track' -import { useInfiniteQuery } from 'react-query' +import { useInfiniteQuery } from '@tanstack/react-query' import { fetchTracks } from '../track' // 100 tracks each page diff --git a/packages/web/api/hooks/useUser.ts b/packages/web/api/hooks/useUser.ts index 1ad88a5..8e91e94 100644 --- a/packages/web/api/hooks/useUser.ts +++ b/packages/web/api/hooks/useUser.ts @@ -2,10 +2,10 @@ import { fetchUserAccount } from '@/web/api/user' import { UserApiNames, FetchUserAccountResponse } from '@/shared/api/User' import { APIs } from '@/shared/CacheAPIs' import { IpcChannels } from '@/shared/IpcChannels' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' export default function useUser() { - return useQuery(UserApiNames.FetchUserAccount, fetchUserAccount, { + return useQuery([UserApiNames.FetchUserAccount], fetchUserAccount, { refetchOnWindowFocus: true, placeholderData: (): FetchUserAccountResponse | undefined => window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, { diff --git a/packages/web/api/hooks/useUserAlbums.ts b/packages/web/api/hooks/useUserAlbums.ts index 12819fa..77f08c0 100644 --- a/packages/web/api/hooks/useUserAlbums.ts +++ b/packages/web/api/hooks/useUserAlbums.ts @@ -1,5 +1,5 @@ import { likeAAlbum } from '@/web/api/album' -import { useMutation, useQuery, useQueryClient } from 'react-query' +import { useMutation, useQuery } from '@tanstack/react-query' import useUser from './useUser' import { IpcChannels } from '@/shared/IpcChannels' import { APIs } from '@/shared/CacheAPIs' @@ -10,11 +10,15 @@ import { } from '@/shared/api/User' import { fetchUserAlbums } from '../user' import toast from 'react-hot-toast' +import reactQueryClient from '@/web/utils/reactQueryClient' +import { cloneDeep } from 'lodash-es' +import { AlbumApiNames, FetchAlbumResponse } from '@/shared/api/Album' export default function useUserAlbums(params: FetchUserAlbumsParams = {}) { const { data: user } = useUser() + const uid = user?.profile?.userId ?? 0 return useQuery( - [UserApiNames.FetchUserAlbums, user?.profile?.userId ?? 0], + [UserApiNames.FetchUserAlbums, uid], () => fetchUserAlbums(params), { refetchOnWindowFocus: true, @@ -28,53 +32,91 @@ export default function useUserAlbums(params: FetchUserAlbumsParams = {}) { } export const useMutationLikeAAlbum = () => { - const queryClient = useQueryClient() const { data: user } = useUser() const { data: userAlbums } = useUserAlbums({ limit: 2000 }) - const uid = user?.account?.id ?? 0 + const uid = user?.profile?.userId ?? 0 const key = [UserApiNames.FetchUserAlbums, uid] return useMutation( - async (album: Album) => { - if (!album.id || userAlbums?.data === undefined) { + async (albumID: number) => { + if (!albumID || userAlbums?.data === undefined) { throw new Error('album id is required or userAlbums is undefined') } const response = await likeAAlbum({ - id: album.id, - t: userAlbums?.data.findIndex(a => a.id === album.id) > -1 ? 2 : 1, + id: albumID, + t: userAlbums?.data.findIndex(a => a.id === albumID) > -1 ? 2 : 1, }) if (response.code !== 200) throw new Error((response as any).msg) return response }, { - onMutate: async album => { + onMutate: async albumID => { // Cancel any outgoing refetches (so they don't overwrite our optimistic update) - await queryClient.cancelQueries(key) + await reactQueryClient.cancelQueries(key) + + console.log(reactQueryClient.getQueryData(key)) + + // 如果还未获取用户收藏的专辑列表,则获取一次 + if (!reactQueryClient.getQueryData(key)) { + await reactQueryClient.fetchQuery(key) + } // Snapshot the previous value - const previousData = queryClient.getQueryData(key) + const previousData = reactQueryClient.getQueryData( + key + ) as FetchUserAlbumsResponse - // Optimistically update to the new value - queryClient.setQueryData(key, old => { - const userAlbums = old as FetchUserAlbumsResponse - const albums = userAlbums.data - const newAlbums = - albums.findIndex(a => a.id === album.id) > -1 - ? albums.filter(a => a.id !== album.id) - : [...albums, album] - return { - ...userAlbums, - data: newAlbums, + const isLiked = !!previousData?.data.find(a => a.id === albumID) + const newAlbums = cloneDeep(previousData!) + + console.log({ isLiked }) + + if (isLiked) { + newAlbums.data = previousData.data.filter(a => a.id !== albumID) + } else { + // 从react-query缓存获取专辑 + + console.log({ albumID }) + + const albumFromCache: FetchAlbumResponse | undefined = + reactQueryClient.getQueryData([ + AlbumApiNames.FetchAlbum, + { id: albumID }, + ]) + + console.log({ albumFromCache }) + + // 从api获取专辑 + const album: FetchAlbumResponse | undefined = albumFromCache + ? albumFromCache + : await reactQueryClient.fetchQuery([ + AlbumApiNames.FetchAlbum, + { id: albumID }, + ]) + + if (!album?.album) { + toast.error('Failed to like album: unable to fetch album info') + throw new Error('unable to fetch album info') } - }) + newAlbums.data.unshift(album.album) + + // Optimistically update to the new value + reactQueryClient.setQueriesData(key, newAlbums) + } + + reactQueryClient.setQueriesData(key, newAlbums) + + console.log({ newAlbums }) // Return a context object with the snapshotted value return { previousData } }, // If the mutation fails, use the context returned from onMutate to roll back - onError: (err, trackID, context) => { - queryClient.setQueryData(key, (context as any).previousData) - toast((err as any).toString()) + onSettled: (data, error, albumID, context) => { + if (data?.code !== 200) { + reactQueryClient.setQueryData(key, (context as any).previousData) + toast((error as any).toString()) + } }, } ) diff --git a/packages/web/api/hooks/useUserArtists.ts b/packages/web/api/hooks/useUserArtists.ts index 9f3670c..c0ce513 100644 --- a/packages/web/api/hooks/useUserArtists.ts +++ b/packages/web/api/hooks/useUserArtists.ts @@ -2,10 +2,19 @@ import { fetchUserArtists } from '@/web/api/user' import { UserApiNames, FetchUserArtistsResponse } from '@/shared/api/User' import { APIs } from '@/shared/CacheAPIs' import { IpcChannels } from '@/shared/IpcChannels' -import { useQuery } from 'react-query' +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import toast from 'react-hot-toast' +import { likeAArtist } from '../artist' +import { ArtistApiNames, FetchArtistResponse } from '@/shared/api/Artist' +import reactQueryClient from '@/web/utils/reactQueryClient' +import { cloneDeep } from 'lodash-es' + +const KEYS = { + useUserArtists: [UserApiNames.FetchUserArtists], +} export default function useUserArtists() { - return useQuery([UserApiNames.FetchUserArtist], fetchUserArtists, { + return useQuery(KEYS.useUserArtists, fetchUserArtists, { refetchOnWindowFocus: true, placeholderData: (): FetchUserArtistsResponse => window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, { @@ -13,3 +22,85 @@ export default function useUserArtists() { }), }) } + +export const useMutationLikeAArtist = () => { + const { data: userLikedArtists } = useUserArtists() + + return useMutation( + async (artistID: number) => { + if (!artistID || !userLikedArtists?.data) { + throw new Error('artistID is required or userLikedArtists is undefined') + } + const response = await likeAArtist({ + id: artistID, + like: !userLikedArtists.data.find(a => a.id === artistID), + }) + if (response.code !== 200) throw new Error((response as any).msg) + return response + }, + { + onMutate: async artistID => { + // Cancel any outgoing refetches (so they don't overwrite our optimistic update) + await reactQueryClient.cancelQueries(KEYS.useUserArtists) + + // 如果还未获取用户收藏的歌手列表,则获取一次 + if (!reactQueryClient.getQueryData(KEYS.useUserArtists)) { + await reactQueryClient.fetchQuery(KEYS.useUserArtists) + } + + // Snapshot the previous value + const previousData = reactQueryClient.getQueryData( + KEYS.useUserArtists + ) as FetchUserArtistsResponse + + const isLiked = !!previousData?.data.find(a => a.id === artistID) + const newLikedArtists = cloneDeep(previousData!) + + if (isLiked) { + newLikedArtists.data = previousData.data.filter( + a => a.id !== artistID + ) + } else { + // 从react-query缓存获取歌手信息 + const artistFromCache: FetchArtistResponse | undefined = + reactQueryClient.getQueryData([ + ArtistApiNames.FetchArtist, + { id: artistID }, + ]) + + // 从api获取歌手信息 + const artist: FetchArtistResponse | undefined = artistFromCache + ? artistFromCache + : await reactQueryClient.fetchQuery([ + ArtistApiNames.FetchArtist, + { id: artistID }, + ]) + + if (!artist?.artist) { + toast.error('Failed to like artist: unable to fetch artist info') + throw new Error('unable to fetch artist info') + } + newLikedArtists.data.unshift(artist.artist) + + // Optimistically update to the new value + reactQueryClient.setQueriesData(KEYS.useUserArtists, newLikedArtists) + } + + reactQueryClient.setQueriesData(KEYS.useUserArtists, newLikedArtists) + + // Return a context object with the snapshotted value + return { previousData } + }, + // If the mutation fails, use the context returned from onMutate to roll back + onSettled: (data, error, artistID, context) => { + if (data?.code !== 200) { + reactQueryClient.setQueryData( + KEYS.useUserArtists, + (context as any).previousData + ) + toast((error as any).toString()) + } + }, + } + ) +} diff --git a/packages/web/api/hooks/useUserLikedTracksIDs.ts b/packages/web/api/hooks/useUserLikedTracksIDs.ts index 02f9b9d..c907399 100644 --- a/packages/web/api/hooks/useUserLikedTracksIDs.ts +++ b/packages/web/api/hooks/useUserLikedTracksIDs.ts @@ -1,6 +1,6 @@ import { likeATrack } from '@/web/api/track' import useUser from './useUser' -import { useMutation, useQueryClient } from 'react-query' +import { useMutation, useQueryClient } from '@tanstack/react-query' import { IpcChannels } from '@/shared/IpcChannels' import { APIs } from '@/shared/CacheAPIs' import { fetchUserLikedTracksIDs } from '../user' @@ -8,8 +8,9 @@ import { FetchUserLikedTracksIDsResponse, UserApiNames, } from '@/shared/api/User' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' import toast from 'react-hot-toast' +import reactQueryClient from '@/web/utils/reactQueryClient' export default function useUserLikedTracksIDs() { const { data: user } = useUser() @@ -33,7 +34,6 @@ export default function useUserLikedTracksIDs() { } export const useMutationLikeATrack = () => { - const queryClient = useQueryClient() const { data: user } = useUser() const { data: userLikedSongs } = useUserLikedTracksIDs() const uid = user?.account?.id ?? 0 @@ -54,13 +54,13 @@ export const useMutationLikeATrack = () => { { onMutate: async trackID => { // Cancel any outgoing refetches (so they don't overwrite our optimistic update) - await queryClient.cancelQueries(key) + await reactQueryClient.cancelQueries(key) // Snapshot the previous value - const previousData = queryClient.getQueryData(key) + const previousData = reactQueryClient.getQueryData(key) // Optimistically update to the new value - queryClient.setQueryData(key, old => { + reactQueryClient.setQueryData(key, old => { const likedSongs = old as FetchUserLikedTracksIDsResponse const ids = likedSongs.ids const newIds = ids.includes(trackID) @@ -77,7 +77,7 @@ export const useMutationLikeATrack = () => { }, // If the mutation fails, use the context returned from onMutate to roll back onError: (err, trackID, context) => { - queryClient.setQueryData(key, (context as any).previousData) + reactQueryClient.setQueryData(key, (context as any).previousData) toast((err as any).toString()) }, } diff --git a/packages/web/api/hooks/useUserListenedRecords.ts b/packages/web/api/hooks/useUserListenedRecords.ts index 812e7eb..da98dd3 100644 --- a/packages/web/api/hooks/useUserListenedRecords.ts +++ b/packages/web/api/hooks/useUserListenedRecords.ts @@ -2,7 +2,7 @@ import { fetchListenedRecords } from '@/web/api/user' import { UserApiNames, FetchListenedRecordsResponse } from '@/shared/api/User' import { APIs } from '@/shared/CacheAPIs' import { IpcChannels } from '@/shared/IpcChannels' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' import useUser from './useUser' export default function useUserListenedRecords(params: { diff --git a/packages/web/api/hooks/useUserPlaylists.ts b/packages/web/api/hooks/useUserPlaylists.ts index 8408d8d..3921070 100644 --- a/packages/web/api/hooks/useUserPlaylists.ts +++ b/packages/web/api/hooks/useUserPlaylists.ts @@ -1,11 +1,14 @@ import { likeAPlaylist } from '@/web/api/playlist' -import { useMutation, useQuery, useQueryClient } from 'react-query' +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import useUser from './useUser' import { IpcChannels } from '@/shared/IpcChannels' import { APIs } from '@/shared/CacheAPIs' import { fetchUserPlaylists } from '@/web/api/user' import { FetchUserPlaylistsResponse, UserApiNames } from '@/shared/api/User' import toast from 'react-hot-toast' +import reactQueryClient from '@/web/utils/reactQueryClient' +import { cloneDeep } from 'lodash-es' +import { FetchPlaylistResponse, PlaylistApiNames } from '@/shared/api/Playlists' export default function useUserPlaylists() { const { data: user } = useUser() @@ -45,21 +48,20 @@ export default function useUserPlaylists() { } export const useMutationLikeAPlaylist = () => { - const queryClient = useQueryClient() const { data: user } = useUser() const { data: userPlaylists } = useUserPlaylists() const uid = user?.account?.id ?? 0 const key = [UserApiNames.FetchUserPlaylists, uid] return useMutation( - async (playlist: Playlist) => { - if (!playlist.id || userPlaylists?.playlist === undefined) { + async (playlistID: number) => { + if (!playlistID || userPlaylists?.playlist === undefined) { throw new Error('playlist id is required or userPlaylists is undefined') } const response = await likeAPlaylist({ - id: playlist.id, + id: playlistID, t: - userPlaylists.playlist.findIndex(p => p.id === playlist.id) > -1 + userPlaylists.playlist.findIndex(p => p.id === playlistID) > -1 ? 2 : 1, }) @@ -67,34 +69,73 @@ export const useMutationLikeAPlaylist = () => { return response }, { - onMutate: async playlist => { + onMutate: async playlistID => { // Cancel any outgoing refetches (so they don't overwrite our optimistic update) - await queryClient.cancelQueries(key) + await reactQueryClient.cancelQueries(key) + + console.log(reactQueryClient.getQueryData(key)) + + // 如果还未获取用户收藏的专辑列表,则获取一次 + if (!reactQueryClient.getQueryData(key)) { + await reactQueryClient.fetchQuery(key) + } // Snapshot the previous value - const previousData = queryClient.getQueryData(key) + const previousData = reactQueryClient.getQueryData( + key + ) as FetchUserPlaylistsResponse - // Optimistically update to the new value - queryClient.setQueryData(key, old => { - const userPlaylists = old as FetchUserPlaylistsResponse - const playlists = userPlaylists.playlist - const newPlaylists = - playlists.findIndex(p => p.id === playlist.id) > -1 - ? playlists.filter(p => p.id !== playlist.id) - : [...playlists, playlist] - return { - ...userPlaylists, - playlist: newPlaylists, + const isLiked = !!previousData?.playlist.find(p => p.id === playlistID) + const newPlaylists = cloneDeep(previousData!) + + console.log({ isLiked }) + + if (isLiked) { + newPlaylists.playlist = previousData.playlist.filter( + p => p.id !== playlistID + ) + } else { + // 从react-query缓存获取歌单信息 + + const playlistFromCache: FetchPlaylistResponse | undefined = + reactQueryClient.getQueryData([ + PlaylistApiNames.FetchPlaylist, + { id: playlistID }, + ]) + + // 从api获取歌单信息 + const playlist: FetchPlaylistResponse | undefined = playlistFromCache + ? playlistFromCache + : await reactQueryClient.fetchQuery([ + PlaylistApiNames.FetchPlaylist, + { id: playlistID }, + ]) + + if (!playlist?.playlist) { + toast.error( + 'Failed to like playlist: unable to fetch playlist info' + ) + throw new Error('unable to fetch playlist info') } - }) + newPlaylists.playlist.splice(1, 0, playlist.playlist) + + // Optimistically update to the new value + reactQueryClient.setQueriesData(key, newPlaylists) + } + + reactQueryClient.setQueriesData(key, newPlaylists) + + console.log({ newPlaylists }) // Return a context object with the snapshotted value return { previousData } }, // If the mutation fails, use the context returned from onMutate to roll back - onError: (err, trackID, context) => { - queryClient.setQueryData(key, (context as any).previousData) - toast((err as any).toString()) + onSettled: (data, error, playlistID, context) => { + if (data?.code !== 200) { + reactQueryClient.setQueryData(key, (context as any).previousData) + toast((error as any).toString()) + } }, } ) diff --git a/packages/web/api/mv.ts b/packages/web/api/mv.ts new file mode 100644 index 0000000..61b9282 --- /dev/null +++ b/packages/web/api/mv.ts @@ -0,0 +1,62 @@ +import { + FetchMVResponse, + FetchMVParams, + FetchMVUrlParams, + FetchMVUrlResponse, +} from '@/shared/api/MV' +import request from '@/web/utils/request' + +// 获取 mv 数据 +export function fetchMV(params: FetchMVParams): Promise { + return request({ + url: '/mv/detail', + method: 'get', + params: { + mvid: params.mvid, + timestamp: new Date().getTime(), + }, + }) +} + +// mv 地址 +export function fetchMVUrl( + params: FetchMVUrlParams +): Promise { + return request({ + url: '/mv/url', + method: 'get', + params, + }) +} + +/** + * 相似 mv + * 说明 : 调用此接口 , 传入 mvid 可获取相似 mv + * @param {number} mvid + */ +export function simiMv(mvid) { + return request({ + url: '/simi/mv', + method: 'get', + params: { mvid }, + }) +} + +/** + * 收藏/取消收藏 MV + * 说明 : 调用此接口,可收藏/取消收藏 MV + * - mvid: mv id + * - t: 1 为收藏,其他为取消收藏 + * @param {Object} params + * @param {number} params.mvid + * @param {number=} params.t + */ + +export function likeAMV(params) { + params.timestamp = new Date().getTime() + return request({ + url: '/mv/sub', + method: 'post', + params, + }) +} diff --git a/packages/web/api/playlist.ts b/packages/web/api/playlist.ts index 2c8b921..307d0b0 100644 --- a/packages/web/api/playlist.ts +++ b/packages/web/api/playlist.ts @@ -11,18 +11,15 @@ import { // 歌单详情 export function fetchPlaylist( - params: FetchPlaylistParams, - noCache: boolean + params: FetchPlaylistParams ): Promise { - const otherParams: { timestamp?: number } = {} - if (noCache) otherParams.timestamp = new Date().getTime() if (!params.s) params.s = 0 // 网易云默认返回8个收藏者,这里设置为0,减少返回的JSON体积 return request({ url: '/playlist/detail', method: 'get', params: { ...params, - ...otherParams, + timestamp: new Date().getTime(), }, }) } diff --git a/packages/web/components/New/Airplay.tsx b/packages/web/components/New/Airplay.tsx new file mode 100644 index 0000000..79cb30f --- /dev/null +++ b/packages/web/components/New/Airplay.tsx @@ -0,0 +1,67 @@ +import player from '@/web/states/player' +import { css, cx } from '@emotion/css' +import { useQuery } from '@tanstack/react-query' +import { useState } from 'react' +import { useSnapshot } from 'valtio' + +const useAirplayDevices = () => { + return useQuery(['useAirplayDevices'], () => + window.ipcRenderer?.invoke('airplay-scan-devices') + ) +} + +const Airplay = () => { + const [showPanel, setShowPanel] = useState(false) + const { data: devices, isLoading } = useAirplayDevices() + const { remoteDevice } = useSnapshot(player) + const selectedAirplayDeviceID = + remoteDevice?.protocol === 'airplay' ? remoteDevice?.id : '' + + return ( +
+
setShowPanel(!showPanel)} + className='flex h-12 w-12 items-center justify-center rounded-full bg-white/20 text-24 text-white' + > + A +
+ + {showPanel && ( +
+ {devices?.devices?.map(device => ( +
player.switchToAirplayDevice(device.identifier)} + > + {device.name} +
+ ))} +
+ )} +
+ ) +} + +export default Airplay diff --git a/packages/web/components/New/ArtistRow.tsx b/packages/web/components/New/ArtistRow.tsx index 5deedcd..875bc01 100644 --- a/packages/web/components/New/ArtistRow.tsx +++ b/packages/web/components/New/ArtistRow.tsx @@ -3,6 +3,7 @@ import { css, cx } from '@emotion/css' import { memo } from 'react' import { useNavigate } from 'react-router-dom' import Image from './Image' +import { prefetchArtist } from '@/web/api/hooks/useArtist' const Artist = ({ artist }: { artist: Artist }) => { const navigate = useNavigate() @@ -11,7 +12,10 @@ const Artist = ({ artist }: { artist: Artist }) => { } return ( -
+
prefetchArtist({ id: artist.id })} + > {/* Title */} {title && ( -

+

{title}

)} {/* Artists */} {artists && ( -
+
{artists.map(artist => (
diff --git a/packages/web/components/New/BlurBackground.tsx b/packages/web/components/New/BlurBackground.tsx index c75beab..d6e938b 100644 --- a/packages/web/components/New/BlurBackground.tsx +++ b/packages/web/components/New/BlurBackground.tsx @@ -3,21 +3,34 @@ import { cx, css } from '@emotion/css' import useIsMobile from '@/web/hooks/useIsMobile' import { useSnapshot } from 'valtio' import uiStates from '@/web/states/uiStates' -import { AnimatePresence, motion } from 'framer-motion' +import { AnimatePresence, motion, useAnimation } from 'framer-motion' import { ease } from '@/web/utils/const' +import { useLocation } from 'react-router-dom' +import { useEffect } from 'react' -const BlurBackground = ({ cover }: { cover?: string }) => { +const BlurBackground = () => { const isMobile = useIsMobile() - const { hideTopbarBackground } = useSnapshot(uiStates) + const { hideTopbarBackground, blurBackgroundImage } = useSnapshot(uiStates) + const location = useLocation() + const animate = useAnimation() + + useEffect(() => { + uiStates.blurBackgroundImage = null + }, [location.pathname]) + + const onLoad = async () => { + animate.start({ opacity: 1 }) + } return ( - {!isMobile && cover && hideTopbarBackground && ( + {!isMobile && blurBackgroundImage && hideTopbarBackground && ( { filter: blur(256px) saturate(1.2); ` )} - src={resizeImage(cover, 'sm')} + src={resizeImage(blurBackgroundImage, 'sm')} /> )} diff --git a/packages/web/components/New/CoverRow.tsx b/packages/web/components/New/CoverRow.tsx index 1125769..4cc3831 100644 --- a/packages/web/components/New/CoverRow.tsx +++ b/packages/web/components/New/CoverRow.tsx @@ -5,6 +5,7 @@ import Image from './Image' import { prefetchAlbum } from '@/web/api/hooks/useAlbum' import { prefetchPlaylist } from '@/web/api/hooks/usePlaylist' import { memo, useCallback } from 'react' +import dayjs from 'dayjs' const Album = ({ album }: { album: Album }) => { const navigate = useNavigate() @@ -16,13 +17,21 @@ const Album = ({ album }: { album: Album }) => { } return ( - +
+ +
+ {album.name} +
+
+ {dayjs(album.publishTime || 0).year()} +
+
) } diff --git a/packages/web/components/New/CoverRowVirtual.tsx b/packages/web/components/New/CoverRowVirtual.tsx index d29f1b6..bd2a366 100644 --- a/packages/web/components/New/CoverRowVirtual.tsx +++ b/packages/web/components/New/CoverRowVirtual.tsx @@ -1,19 +1,16 @@ import { resizeImage } from '@/web/utils/common' import { cx } from '@emotion/css' import { useNavigate } from 'react-router-dom' -import Image from './Image' import { prefetchAlbum } from '@/web/api/hooks/useAlbum' import { prefetchPlaylist } from '@/web/api/hooks/usePlaylist' -import { useVirtualizer } from '@tanstack/react-virtual' -import { CSSProperties, useRef } from 'react' +import { Virtuoso } from 'react-virtuoso' +import { CSSProperties } from 'react' const CoverRow = ({ albums, playlists, title, className, - containerClassName, - containerStyle, }: { title?: string className?: string @@ -34,9 +31,6 @@ const CoverRow = ({ if (playlists) prefetchPlaylist({ id }) } - // The scrollable element for your list - const parentRef = useRef(null) - type Item = Album | Playlist const items: Item[] = albums || playlists || [] const rows = items.reduce((rows: Item[][], item: Item, index: number) => { @@ -49,29 +43,6 @@ const CoverRow = ({ return rows }, []) - // The virtualizer - const rowVirtualizer = useVirtualizer({ - count: rows.length, - getScrollElement: () => parentRef.current, - overscan: 5, - estimateSize: () => { - const containerWidth = parentRef.current?.clientWidth - console.log(parentRef.current?.clientWidth) - if (!containerWidth) { - return 192 - } - const gridGapY = 24 - const gridGapX = 40 - const gridColumns = 4 - console.log( - (containerWidth - (gridColumns - 1) * gridGapX) / gridColumns + gridGapY - ) - return ( - (containerWidth - (gridColumns - 1) * gridGapX) / gridColumns + gridGapY - ) - }, - }) - return (
{/* Title */} @@ -81,46 +52,43 @@ const CoverRow = ({ )} -
-
- {rowVirtualizer.getVirtualItems().map((row: any) => ( -
- {rows[row.index].map((item: Item) => ( - goTo(item.id)} - key={item.id} - alt={item.name} - src={resizeImage( + el.getBoundingClientRect().height + 24} + totalCount={rows.length} + components={{ + Header: () =>
, + Footer: () =>
, + }} + itemContent={(index, row) => ( +
+ {row.map((item: Item) => ( + goTo(item.id)} + key={item.id} + alt={item.name} + src={resizeImage( + item?.picUrl || + (item as Playlist)?.coverImgUrl || item?.picUrl || - (item as Playlist)?.coverImgUrl || - item?.picUrl || - '', - 'md' - )} - className='aspect-square rounded-24' - onMouseOver={() => prefetch(item.id)} - /> - ))} -
- ))} -
-
+ '', + 'md' + )} + className='rounded-24' + onMouseOver={() => prefetch(item.id)} + /> + ))} +
+ )} + />
) } diff --git a/packages/web/components/New/Devtool.tsx b/packages/web/components/New/Devtool.tsx index 72cebdf..1c7a60a 100644 --- a/packages/web/components/New/Devtool.tsx +++ b/packages/web/components/New/Devtool.tsx @@ -1,5 +1,4 @@ -import useBreakpoint from '@/web/hooks/useBreakpoint' -import { ReactQueryDevtools } from 'react-query/devtools' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import useIsMobile from '@/web/hooks/useIsMobile' const Devtool = () => { @@ -10,10 +9,19 @@ const Devtool = () => { toggleButtonProps={{ style: { position: 'fixed', - bottom: isMobile ? 'auto' : 0, - right: 0, - top: isMobile ? 0 : 'auto', - left: 'auto', + ...(isMobile + ? { + top: 0, + right: 0, + bottom: 'auto', + left: 'atuo', + } + : { + top: 36, + right: 148, + bottom: 'atuo', + left: 'auto', + }), }, }} /> diff --git a/packages/web/components/New/ErrorBoundary.tsx b/packages/web/components/New/ErrorBoundary.tsx index 81de4d0..20fda06 100644 --- a/packages/web/components/New/ErrorBoundary.tsx +++ b/packages/web/components/New/ErrorBoundary.tsx @@ -1,42 +1,34 @@ import { ReactNode } from 'react' -import { ErrorBoundary as ErrorBoundaryRaw } from 'react-error-boundary' - -function ErrorFallback({ - error, - resetErrorBoundary, -}: { - error: Error - resetErrorBoundary: () => void -}) { - return ( -
-
-

Something went wrong:

-
{error.message}
- -
-
- ) -} +import * as Sentry from '@sentry/react' const ErrorBoundary = ({ children }: { children: ReactNode }) => { return ( - { - // reset the state of your app so the error doesn't happen again - }} + ( +
+
+

Something went wrong:

+
+              {error.toString()}
+            
+
+ {componentStack?.trim()} +
+ +
+
+ )} > {children} -
+ ) } diff --git a/packages/web/components/New/Image.tsx b/packages/web/components/New/Image.tsx index c8d5371..bc95532 100644 --- a/packages/web/components/New/Image.tsx +++ b/packages/web/components/New/Image.tsx @@ -92,7 +92,7 @@ const ImageDesktop = ({ {placeholder && ( )} diff --git a/packages/web/components/New/Layout.tsx b/packages/web/components/New/Layout.tsx index b48a282..7379f85 100644 --- a/packages/web/components/New/Layout.tsx +++ b/packages/web/components/New/Layout.tsx @@ -7,9 +7,14 @@ import player from '@/web/states/player' import { useSnapshot } from 'valtio' import Login from './Login' import TrafficLight from './TrafficLight' +import BlurBackground from './BlurBackground' +import Airplay from './Airplay' +import TitleBar from './TitleBar' +import uiStates from '@/web/states/uiStates' const Layout = () => { const playerSnapshot = useSnapshot(player) + const { fullscreen } = useSnapshot(uiStates) const showPlayer = !!playerSnapshot.track return ( @@ -17,24 +22,10 @@ const Layout = () => { id='layout' className={cx( 'relative grid h-screen select-none overflow-hidden bg-white dark:bg-black', - window.env?.isElectron && 'rounded-24', - css` - grid-template-columns: 6.5rem auto 358px; - grid-template-rows: 132px auto; - `, - showPlayer - ? css` - grid-template-areas: - 'menubar main -' - 'menubar main player'; - ` - : css` - grid-template-areas: - 'menubar main main' - 'menubar main main'; - ` + window.env?.isElectron && !fullscreen && 'rounded-24' )} > +
@@ -46,6 +37,10 @@ const Layout = () => {
)} + + {window.env?.isWindows && } + + {/* {window.env?.isElectron && } */}
) } diff --git a/packages/web/components/New/Login/Login.tsx b/packages/web/components/New/Login/Login.tsx index 17e5ae2..72676e9 100644 --- a/packages/web/components/New/Login/Login.tsx +++ b/packages/web/components/New/Login/Login.tsx @@ -8,6 +8,7 @@ import Icon from '@/web/components/Icon' import LoginWithPhoneOrEmail from './LoginWithPhoneOrEmail' import LoginWithQRCode from './LoginWithQRCode' import persistedUiStates from '@/web/states/persistedUiStates' +import useUser from '@/web/api/hooks/useUser' const OR = ({ children, @@ -26,7 +27,7 @@ const OR = ({
- ) -} - -const NowPlaying = () => { - const { state, track } = useSnapshot(player) - - return ( -
- {/* Cover */} - - - {/* Info & Controls */} -
- {/* Track Info */} -
- {track?.name} -
- - - {/* Dividing line */} -
- - {/* Progress */} - - - {/* Controls */} -
- - -
- - - -
- - -
-
-
- ) -} - -export default NowPlaying diff --git a/packages/web/components/New/NowPlaying/Controls.tsx b/packages/web/components/New/NowPlaying/Controls.tsx new file mode 100644 index 0000000..8ca9ecf --- /dev/null +++ b/packages/web/components/New/NowPlaying/Controls.tsx @@ -0,0 +1,114 @@ +import persistedUiStates from '@/web/states/persistedUiStates' +import player from '@/web/states/player' +import { ease } from '@/web/utils/const' +import { cx, css } from '@emotion/css' +import { MotionConfig, motion } from 'framer-motion' +import { useSnapshot } from 'valtio' +import Icon from '../../Icon' +import { State as PlayerState } from '@/web/utils/player' +import useUserLikedTracksIDs, { + useMutationLikeATrack, +} from '@/web/api/hooks/useUserLikedTracksIDs' + +const LikeButton = () => { + const { track } = useSnapshot(player) + const { data: likedIDs } = useUserLikedTracksIDs() + const isLiked = !!likedIDs?.ids?.find(id => id === track?.id) + const likeATrack = useMutationLikeATrack() + const { minimizePlayer: mini } = useSnapshot(persistedUiStates) + + return ( + track?.id && likeATrack.mutateAsync(track.id)} + className='text-black/90 transition-colors duration-400 dark:text-white/40 hover:dark:text-white/90' + > + + + ) +} + +const Controls = () => { + const { state, track } = useSnapshot(player) + const { minimizePlayer: mini } = useSnapshot(persistedUiStates) + + return ( + + + {/* Minimize */} + { + persistedUiStates.minimizePlayer = !mini + }} + > + + + + {/* Media controls */} +
+ track && player.prevTrack()} + disabled={!track} + className='rounded-full bg-black/10 p-2.5 transition-colors duration-400 dark:bg-white/10 hover:dark:bg-white/20' + > + + + track && player.playOrPause()} + className='rounded-full bg-black/10 p-2.5 transition-colors duration-400 dark:bg-white/10 hover:dark:bg-white/20' + > + + + track && player.nextTrack()} + disabled={!track} + className='rounded-full bg-black/10 p-2.5 transition-colors duration-400 dark:bg-white/10 hover:dark:bg-white/20' + > + + +
+ + {/* Like */} + +
+
+ ) +} + +export default Controls diff --git a/packages/web/components/New/NowPlaying/Cover.tsx b/packages/web/components/New/NowPlaying/Cover.tsx new file mode 100644 index 0000000..7d46fe9 --- /dev/null +++ b/packages/web/components/New/NowPlaying/Cover.tsx @@ -0,0 +1,62 @@ +import player from '@/web/states/player' +import { resizeImage } from '@/web/utils/common' +import { ease } from '@/web/utils/const' +import { cx } from '@emotion/css' +import { useAnimation, motion } from 'framer-motion' +import { useState, useRef, useEffect } from 'react' +import { useNavigate } from 'react-router-dom' +import { useSnapshot } from 'valtio' + +const Cover = () => { + const playerSnapshot = useSnapshot(player) + const [cover, setCover] = useState('') + const animationStartTime = useRef(0) + const controls = useAnimation() + const duration = 150 // ms + const navigate = useNavigate() + + useEffect(() => { + const resizedCover = resizeImage( + playerSnapshot.track?.al.picUrl || '', + 'lg' + ) + const animate = async () => { + animationStartTime.current = Date.now() + await controls.start({ opacity: 0 }) + setCover(resizedCover) + } + animate() + }, [controls, playerSnapshot.track?.al.picUrl]) + + // 防止狂点下一首或上一首造成封面与歌曲不匹配的问题 + useEffect(() => { + const realCover = resizeImage(playerSnapshot.track?.al.picUrl ?? '', 'lg') + if (cover !== realCover) setCover(realCover) + }, [cover, playerSnapshot.track?.al.picUrl]) + + const onLoad = () => { + const passedTime = Date.now() - animationStartTime.current + controls.start({ + opacity: 1, + transition: { + delay: passedTime > duration ? 0 : (duration - passedTime) / 1000, + }, + }) + } + + return ( + { + const id = playerSnapshot.track?.al.id + if (id) navigate(`/album/${id}`) + }} + /> + ) +} + +export default Cover diff --git a/packages/web/components/New/NowPlaying.stories.tsx b/packages/web/components/New/NowPlaying/NowPlaying.stories.tsx similarity index 92% rename from packages/web/components/New/NowPlaying.stories.tsx rename to packages/web/components/New/NowPlaying/NowPlaying.stories.tsx index 831473a..989b15a 100644 --- a/packages/web/components/New/NowPlaying.stories.tsx +++ b/packages/web/components/New/NowPlaying/NowPlaying.stories.tsx @@ -1,7 +1,7 @@ import React from 'react' import { ComponentStory, ComponentMeta } from '@storybook/react' import NowPlaying from './NowPlaying' -import tracks from '../../.storybook/mock/tracks' +import tracks from '@/web/.storybook/mock/tracks' import { sample } from 'lodash-es' export default { diff --git a/packages/web/components/New/NowPlaying/NowPlaying.tsx b/packages/web/components/New/NowPlaying/NowPlaying.tsx new file mode 100644 index 0000000..ca74b9a --- /dev/null +++ b/packages/web/components/New/NowPlaying/NowPlaying.tsx @@ -0,0 +1,65 @@ +import { css, cx } from '@emotion/css' +import player from '@/web/states/player' +import { useSnapshot } from 'valtio' +import { AnimatePresence, motion } from 'framer-motion' +import ArtistInline from '@/web/components/New/ArtistsInLine' +import persistedUiStates from '@/web/states/persistedUiStates' +import Controls from './Controls' +import Cover from './Cover' +import Progress from './Progress' + +const NowPlaying = () => { + const { track } = useSnapshot(player) + const { minimizePlayer } = useSnapshot(persistedUiStates) + + return ( + <> + {/* Now Playing */} + + {!minimizePlayer && ( + + {/* Cover */} + + + {/* Info & Controls */} +
+ {/* Track Info */} +
+ {track?.name} +
+ + + {/* Dividing line */} +
+ + {/* Progress */} + + + {/* Controls placeholder */} +
+
+
+ )} +
+ + {/* Controls (for Animation) */} + + + ) +} + +export default NowPlaying diff --git a/packages/web/components/New/NowPlaying/Progress.tsx b/packages/web/components/New/NowPlaying/Progress.tsx new file mode 100644 index 0000000..74e3a8d --- /dev/null +++ b/packages/web/components/New/NowPlaying/Progress.tsx @@ -0,0 +1,29 @@ +import player from '@/web/states/player' +import { formatDuration } from '@/web/utils/common' +import { useSnapshot } from 'valtio' +import Slider from '../Slider' + +const Progress = () => { + const { track, progress } = useSnapshot(player) + + return ( +
+ { + player.progress = value + }} + onlyCallOnChangeAfterDragEnded={true} + /> + +
+ {formatDuration(progress * 1000, 'en', 'hh:mm:ss')} + {formatDuration(track?.dt || 0, 'en', 'hh:mm:ss')} +
+
+ ) +} + +export default Progress diff --git a/packages/web/components/New/NowPlaying/index.tsx b/packages/web/components/New/NowPlaying/index.tsx new file mode 100644 index 0000000..ff8854d --- /dev/null +++ b/packages/web/components/New/NowPlaying/index.tsx @@ -0,0 +1,3 @@ +import NowPlaying from './NowPlaying' + +export default NowPlaying diff --git a/packages/web/components/New/PageTransition.tsx b/packages/web/components/New/PageTransition.tsx index c4dafca..a0810ec 100644 --- a/packages/web/components/New/PageTransition.tsx +++ b/packages/web/components/New/PageTransition.tsx @@ -1,4 +1,4 @@ -import { motion } from 'framer-motion' +import { motion, MotionConfig } from 'framer-motion' import { ease } from '@/web/utils/const' import useIsMobile from '@/web/hooks/useIsMobile' import scrollPositions from '@/web/states/scrollPositions' @@ -26,14 +26,16 @@ const PageTransition = ({ } return ( - - {children} - + + + {children} + + ) } diff --git a/packages/web/components/New/Player.tsx b/packages/web/components/New/Player.tsx index 575aace..8bd9703 100644 --- a/packages/web/components/New/Player.tsx +++ b/packages/web/components/New/Player.tsx @@ -1,22 +1,39 @@ import { css, cx } from '@emotion/css' +import persistedUiStates from '@/web/states/persistedUiStates' +import { useSnapshot } from 'valtio' import NowPlaying from './NowPlaying' import PlayingNext from './PlayingNext' +import { AnimatePresence, motion, MotionConfig } from 'framer-motion' +import { ease } from '@/web/utils/const' const Player = () => { + const { minimizePlayer } = useSnapshot(persistedUiStates) + return ( -
- -
+ +
+ + {!minimizePlayer && ( + + + + )} + +
-
+ ) } diff --git a/packages/web/components/New/PlayingNext.tsx b/packages/web/components/New/PlayingNext.tsx index 5aef900..d7752f6 100644 --- a/packages/web/components/New/PlayingNext.tsx +++ b/packages/web/components/New/PlayingNext.tsx @@ -15,7 +15,7 @@ const Header = () => { return (
@@ -26,7 +26,7 @@ const Header = () => {
-
+
@@ -147,11 +147,11 @@ const TrackList = ({ className }: { className?: string }) => { ) } -const PlayingNext = ({ className }: { className?: string }) => { +const PlayingNext = () => { return ( <>
- + ) } diff --git a/packages/web/components/New/PlayingNextMobile.tsx b/packages/web/components/New/PlayingNextMobile.tsx index 7ba5cd3..6d7354c 100644 --- a/packages/web/components/New/PlayingNextMobile.tsx +++ b/packages/web/components/New/PlayingNextMobile.tsx @@ -1,13 +1,7 @@ import { css, cx } from '@emotion/css' -import { - motion, - useMotionValue, - useDragControls, - AnimatePresence, -} from 'framer-motion' -import { useEffect, useState } from 'react' +import { motion, useDragControls, AnimatePresence } from 'framer-motion' +import { useState } from 'react' import { useLockBodyScroll } from 'react-use' -import { isIosPwa } from '@/web/utils/common' import PlayingNext from './PlayingNext' import { ease } from '@/web/utils/const' import { useSnapshot } from 'valtio' diff --git a/packages/web/components/New/Router.tsx b/packages/web/components/New/Router.tsx index 500a20b..7745fce 100644 --- a/packages/web/components/New/Router.tsx +++ b/packages/web/components/New/Router.tsx @@ -10,6 +10,7 @@ const Browse = React.lazy(() => import('@/web/pages/New/Browse')) const Album = React.lazy(() => import('@/web/pages/New/Album')) const Playlist = React.lazy(() => import('@/web/pages/New/Playlist')) const Artist = React.lazy(() => import('@/web/pages/New/Artist')) +const MV = React.lazy(() => import('@/web/pages/New/MV')) const lazy = (component: ReactNode) => { return {component} @@ -27,6 +28,7 @@ const Router = () => { )} /> )} /> )} /> + )} /> )} /> )}> )} /> diff --git a/packages/web/components/New/ScrollRestoration.tsx b/packages/web/components/New/ScrollRestoration.tsx index b80dd8f..03924ba 100644 --- a/packages/web/components/New/ScrollRestoration.tsx +++ b/packages/web/components/New/ScrollRestoration.tsx @@ -7,7 +7,7 @@ const ScrollRestoration = () => { const main = document.querySelector('main') const handleScroll = throttle(() => { scrollPositions.set(window.location.pathname, main?.scrollTop ?? 0) - }, 100) + }, 200) main?.addEventListener('scroll', handleScroll) return () => { main?.removeEventListener('scroll', handleScroll) diff --git a/packages/web/components/New/TitleBar.tsx b/packages/web/components/New/TitleBar.tsx new file mode 100644 index 0000000..44328ab --- /dev/null +++ b/packages/web/components/New/TitleBar.tsx @@ -0,0 +1,75 @@ +import player from '@/web/states/player' +import Icon from '../Icon' +import { IpcChannels } from '@/shared/IpcChannels' +import useIpcRenderer from '@/web/hooks/useIpcRenderer' +import { useState, useMemo } from 'react' +import { useSnapshot } from 'valtio' +import { css, cx } from '@emotion/css' + +const Controls = () => { + const [isMaximized, setIsMaximized] = useState(false) + + useIpcRenderer(IpcChannels.IsMaximized, (e, value) => { + setIsMaximized(value) + }) + + const minimize = () => { + window.ipcRenderer?.send(IpcChannels.Minimize) + } + + const maxRestore = () => { + window.ipcRenderer?.send(IpcChannels.MaximizeOrUnmaximize) + } + + const close = () => { + window.ipcRenderer?.send(IpcChannels.Close) + } + + const classNames = cx( + 'flex items-center justify-center text-white/80 hover:text-white hover:bg-white/20 transition duration-400', + css` + height: 28px; + width: 48px; + border-radius: 4px; + ` + ) + + return ( +
+ + + +
+ ) +} + +const TitleBar = () => { + return ( +
+
+
+ +
+
+ ) +} + +export default TitleBar diff --git a/packages/web/components/New/Topbar/NavigationButtons.tsx b/packages/web/components/New/Topbar/NavigationButtons.tsx index 61e595b..4e020d2 100644 --- a/packages/web/components/New/Topbar/NavigationButtons.tsx +++ b/packages/web/components/New/Topbar/NavigationButtons.tsx @@ -4,6 +4,9 @@ import { useNavigate } from 'react-router-dom' import { ease } from '@/web/utils/const' import Icon from '../../Icon' +const buttonClassNames = + 'app-region-no-drag rounded-full bg-white/10 p-2.5 text-white/40 backdrop-blur-3xl transition-colors duration-400 hover:bg-white/20 hover:text-white/60' + const NavigationButtons = () => { const navigate = useNavigate() const controlsBack = useAnimation() @@ -18,10 +21,10 @@ const NavigationButtons = () => { await controlsBack.start({ x: -5 }) await controlsBack.start({ x: 0 }) }} - className='app-region-no-drag rounded-full bg-white/10 p-2.5 text-white/40 backdrop-blur-3xl' + className={buttonClassNames} > - + - -
- -
-
-
- ) -} - -export default TrackListHeader diff --git a/packages/web/components/New/TrackListHeader/Actions.tsx b/packages/web/components/New/TrackListHeader/Actions.tsx new file mode 100644 index 0000000..85ddffa --- /dev/null +++ b/packages/web/components/New/TrackListHeader/Actions.tsx @@ -0,0 +1,42 @@ +import Icon from '../../Icon' + +const Actions = ({ + onPlay, + onLike, + isLiked, +}: { + isLiked?: boolean + onPlay: () => void + onLike?: () => void +}) => { + return ( +
+
+ {/* Menu */} + + {/* Like */} + {onLike && ( + + )} +
+ +
+ ) +} + +export default Actions diff --git a/packages/web/components/New/TrackListHeader/Cover.tsx b/packages/web/components/New/TrackListHeader/Cover.tsx new file mode 100644 index 0000000..80fe6f3 --- /dev/null +++ b/packages/web/components/New/TrackListHeader/Cover.tsx @@ -0,0 +1,33 @@ +import { isIOS, isSafari, resizeImage } from '@/web/utils/common' +import Image from '@/web/components/New/Image' +import { memo, useEffect } from 'react' +import useVideoCover from '@/web/hooks/useVideoCover' +import { motion } from 'framer-motion' +import { ease } from '@/web/utils/const' +import useAppleMusicAlbum from '@/web/hooks/useAppleMusicAlbum' +import uiStates from '@/web/states/uiStates' +import VideoCover from './VideoCover' + +const Cover = memo( + ({ cover, videoCover }: { cover?: string; videoCover?: string }) => { + useEffect(() => { + if (cover) uiStates.blurBackgroundImage = cover + }, [cover]) + + return ( + <> +
+ + + {videoCover && } +
+ + ) + } +) +Cover.displayName = 'Cover' + +export default Cover diff --git a/packages/web/components/New/TrackListHeader/Info.tsx b/packages/web/components/New/TrackListHeader/Info.tsx new file mode 100644 index 0000000..8531c65 --- /dev/null +++ b/packages/web/components/New/TrackListHeader/Info.tsx @@ -0,0 +1,59 @@ +import { formatDate } from '@/web/utils/common' +import Icon from '@/web/components/Icon' +import dayjs from 'dayjs' +import { useNavigate } from 'react-router-dom' +import useIsMobile from '@/web/hooks/useIsMobile' +import { ReactNode } from 'react' + +const Info = ({ + title, + creatorName, + creatorLink, + description, + extraInfo, +}: { + title?: string + creatorName?: string + creatorLink?: string + description?: string + extraInfo?: string | ReactNode +}) => { + const navigate = useNavigate() + const isMobile = useIsMobile() + + return ( +
+ {/* Title */} +
+ {title} +
+ + {/* Creator */} +
+ creatorLink && navigate(creatorLink)} + className='text-24 font-medium transition-colors duration-300 dark:text-white/40 hover:dark:text-neutral-100 ' + > + {creatorName} + +
+ + {/* Extra info */} +
+ {extraInfo} +
+ + {/* Description */} + {!isMobile && ( +
+ )} +
+ ) +} + +export default Info diff --git a/packages/web/components/New/TrackListHeader.stories.tsx b/packages/web/components/New/TrackListHeader/TrackListHeader.stories.tsx similarity index 100% rename from packages/web/components/New/TrackListHeader.stories.tsx rename to packages/web/components/New/TrackListHeader/TrackListHeader.stories.tsx diff --git a/packages/web/components/New/TrackListHeader/TrackListHeader.tsx b/packages/web/components/New/TrackListHeader/TrackListHeader.tsx new file mode 100644 index 0000000..660dda7 --- /dev/null +++ b/packages/web/components/New/TrackListHeader/TrackListHeader.tsx @@ -0,0 +1,60 @@ +import { css, cx } from '@emotion/css' +import Cover from './Cover' +import Actions from './Actions' +import Info from './Info' +import React from 'react' + +interface Props { + className?: string + title?: string + creatorName?: string + creatorLink?: string + description?: string + extraInfo?: string | React.ReactNode + cover?: string + videoCover?: string + isLiked: boolean + onPlay: () => void + onLike?: () => void +} + +const TrackListHeader = ({ + className, + title, + creatorName, + creatorLink, + description, + extraInfo, + cover, + videoCover, + isLiked, + onPlay, + onLike, +}: Props) => { + return ( +
+ + +
+ + +
+
+ ) +} + +const memoized = React.memo(TrackListHeader) +memoized.displayName = 'TrackListHeader' + +export default memoized diff --git a/packages/web/components/New/TrackListHeader/VideoCover.tsx b/packages/web/components/New/TrackListHeader/VideoCover.tsx new file mode 100644 index 0000000..92a95a7 --- /dev/null +++ b/packages/web/components/New/TrackListHeader/VideoCover.tsx @@ -0,0 +1,51 @@ +import { useEffect, useRef } from 'react' +import Hls from 'hls.js' +import { injectGlobal } from '@emotion/css' +import { isIOS, isSafari } from '@/web/utils/common' +import { motion } from 'framer-motion' + +injectGlobal` + .plyr__video-wrapper, + .plyr--video { + background-color: transparent !important; + } +` + +const VideoCover = ({ videoCover }: { videoCover?: string }) => { + const ref = useRef(null) + const hls = useRef(new Hls()) + + useEffect(() => { + if (videoCover && Hls.isSupported()) { + const video = document.querySelector('#video-cover') as HTMLVideoElement + hls.current.loadSource(videoCover) + hls.current.attachMedia(video) + } + }, [videoCover]) + + return ( + + {isSafari ? ( + + ) : ( +
+
+ )} +
+ ) +} + +export default VideoCover diff --git a/packages/web/components/New/TrackListHeader/index.tsx b/packages/web/components/New/TrackListHeader/index.tsx new file mode 100644 index 0000000..7a7bee7 --- /dev/null +++ b/packages/web/components/New/TrackListHeader/index.tsx @@ -0,0 +1,3 @@ +import TrackListHeader from './TrackListHeader' + +export default TrackListHeader diff --git a/packages/web/components/New/TrafficLight.tsx b/packages/web/components/New/TrafficLight.tsx index d7206d3..09f9414 100644 --- a/packages/web/components/New/TrafficLight.tsx +++ b/packages/web/components/New/TrafficLight.tsx @@ -1,15 +1,10 @@ -import { useState } from 'react' -import { IpcChannels } from '@/shared/IpcChannels' -import useIpcRenderer from '@/web/hooks/useIpcRenderer' +import { useSnapshot } from 'valtio' +import uiStates from '@/web/states/uiStates' const TrafficLight = () => { - const [isMaximized, setIsMaximized] = useState(false) + const { fullscreen } = useSnapshot(uiStates) - useIpcRenderer(IpcChannels.IsMaximized, (e, value) => { - setIsMaximized(value) - }) - - if (isMaximized) { + if (fullscreen) { return <> } diff --git a/packages/web/hooks/useAppleMusicAlbum.ts b/packages/web/hooks/useAppleMusicAlbum.ts index a3ab51e..d1c93bc 100644 --- a/packages/web/hooks/useAppleMusicAlbum.ts +++ b/packages/web/hooks/useAppleMusicAlbum.ts @@ -1,5 +1,5 @@ import { IpcChannels } from '@/shared/IpcChannels' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' export default function useAppleMusicAlbum(props: { id?: number diff --git a/packages/web/hooks/useAppleMusicArtist.ts b/packages/web/hooks/useAppleMusicArtist.ts index 69dfaf9..295a7f4 100644 --- a/packages/web/hooks/useAppleMusicArtist.ts +++ b/packages/web/hooks/useAppleMusicArtist.ts @@ -1,7 +1,7 @@ import { AppleMusicArtist } from '@/shared/AppleMusic' import { APIs } from '@/shared/CacheAPIs' import { IpcChannels } from '@/shared/IpcChannels' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' export default function useAppleMusicArtist(props: { id?: number diff --git a/packages/web/hooks/useVideoCover.ts b/packages/web/hooks/useVideoCover.ts index 4555e49..7b07dfb 100644 --- a/packages/web/hooks/useVideoCover.ts +++ b/packages/web/hooks/useVideoCover.ts @@ -1,5 +1,5 @@ import axios from 'axios' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' export default function useVideoCover(props: { id?: number diff --git a/packages/web/ipcRenderer.ts b/packages/web/ipcRenderer.ts index b08f813..b9bbb16 100644 --- a/packages/web/ipcRenderer.ts +++ b/packages/web/ipcRenderer.ts @@ -4,6 +4,7 @@ import { IpcChannelsReturns, IpcChannelsParams, } from '@/shared/IpcChannels' +import uiStates from './states/uiStates' const on = ( channel: T, @@ -36,4 +37,8 @@ export function ipcRenderer() { on(IpcChannels.Repeat, (e, mode) => { player.repeatMode = mode }) + + on(IpcChannels.FullscreenStateChange, (e, isFullscreen) => { + uiStates.fullscreen = isFullscreen + }) } diff --git a/packages/web/main.tsx b/packages/web/main.tsx index 52ad3ab..8b2c44c 100644 --- a/packages/web/main.tsx +++ b/packages/web/main.tsx @@ -2,7 +2,14 @@ import './utils/initLog' import './utils/theme' import { StrictMode } from 'react' import * as ReactDOMClient from 'react-dom/client' -import { BrowserRouter } from 'react-router-dom' +import { + Routes, + BrowserRouter, + useLocation, + useNavigationType, + createRoutesFromChildren, + matchRoutes, +} from 'react-router-dom' import * as Sentry from '@sentry/react' import { BrowserTracing } from '@sentry/tracing' import 'virtual:svg-icons-register' @@ -12,14 +19,25 @@ import App from './AppNew' import pkg from '../../package.json' import ReactGA from 'react-ga4' import { ipcRenderer } from './ipcRenderer' -import { QueryClientProvider } from 'react-query' +import { QueryClientProvider } from '@tanstack/react-query' import reactQueryClient from '@/web/utils/reactQueryClient' +import React from 'react' ReactGA.initialize('G-KMJJCFZDKF') Sentry.init({ dsn: 'https://7cc7879b42ba4bed9f66fb6752558475@o436528.ingest.sentry.io/6274630', - integrations: [new BrowserTracing()], + integrations: [ + new BrowserTracing({ + routingInstrumentation: Sentry.reactRouterV6Instrumentation( + React.useEffect, + useLocation, + useNavigationType, + createRoutesFromChildren, + matchRoutes + ), + }), + ], release: `yesplaymusic@${pkg.version}`, environment: import.meta.env.MODE, diff --git a/packages/web/package.json b/packages/web/package.json index 097e2f8..ffa3199 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -24,8 +24,10 @@ }, "dependencies": { "@emotion/css": "^11.9.0", - "@sentry/react": "^6.19.7", - "@sentry/tracing": "^6.19.7", + "@sentry/react": "^7.8.0", + "@sentry/tracing": "^7.8.0", + "@tanstack/react-query": "^4.0.10", + "@tanstack/react-query-devtools": "^4.0.10", "ahooks": "^3.4.1", "axios": "^0.27.2", "color.js": "^1.2.0", @@ -37,18 +39,15 @@ "js-cookie": "^3.0.1", "lodash-es": "^4.17.21", "md5": "^2.3.0", - "plyr": "^3.7.2", "plyr-react": "^5.0.2", "qrcode": "^1.5.0", "react": "^18.1.0", "react-dom": "^18.1.0", - "react-error-boundary": "^3.1.4", "react-ga4": "^1.4.1", "react-hot-toast": "^2.2.0", - "react-query": "^3.38.0", "react-router-dom": "^6.3.0", "react-use": "^17.4.0", - "react-virtuoso": "^2.16.1", + "react-virtuoso": "^2.16.5", "valtio": "^1.6.1" }, "devDependencies": { diff --git a/packages/web/pages/Home.tsx b/packages/web/pages/Home.tsx index 52f3c77..5f08ffd 100644 --- a/packages/web/pages/Home.tsx +++ b/packages/web/pages/Home.tsx @@ -8,14 +8,14 @@ import FMCard from '@/web/components/FMCard' import { PlaylistApiNames } from '@/shared/api/Playlists' import { APIs } from '@/shared/CacheAPIs' import { IpcChannels } from '@/shared/IpcChannels' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' export default function Home() { const { data: dailyRecommendPlaylists, isLoading: isLoadingDailyRecommendPlaylists, } = useQuery( - PlaylistApiNames.FetchDailyRecommendPlaylists, + [PlaylistApiNames.FetchDailyRecommendPlaylists], fetchDailyRecommendPlaylists, { retry: false, @@ -30,7 +30,7 @@ export default function Home() { data: recommendedPlaylists, isLoading: isLoadingRecommendedPlaylists, } = useQuery( - PlaylistApiNames.FetchRecommendedPlaylists, + [PlaylistApiNames.FetchRecommendedPlaylists], () => { return fetchRecommendedPlaylists({}) }, diff --git a/packages/web/pages/Login.tsx b/packages/web/pages/Login.tsx index 92a03aa..833ba51 100644 --- a/packages/web/pages/Login.tsx +++ b/packages/web/pages/Login.tsx @@ -13,7 +13,7 @@ import { useInterval } from 'react-use' import { cx } from '@emotion/css' import { useState, useMemo, useEffect } from 'react' import toast from 'react-hot-toast' -import { useMutation, useQuery } from 'react-query' +import { useMutation, useQuery } from '@tanstack/react-query' import { useNavigate } from 'react-router-dom' import { useSnapshot } from 'valtio' @@ -327,7 +327,7 @@ const LoginWithQRCode = () => { status: keyStatus, refetch: refetchKey, } = useQuery( - 'qrCodeKey', + ['qrCodeKey'], async () => { const result = await fetchLoginQrCodeKey() if (result.data.code !== 200) { diff --git a/packages/web/pages/New/Album/Album.tsx b/packages/web/pages/New/Album/Album.tsx new file mode 100644 index 0000000..6bac703 --- /dev/null +++ b/packages/web/pages/New/Album/Album.tsx @@ -0,0 +1,54 @@ +import TrackListHeader from '@/web/components/New/TrackListHeader' +import useAlbum from '@/web/api/hooks/useAlbum' +import useTracks from '@/web/api/hooks/useTracks' +import { NavLink, useParams } from 'react-router-dom' +import PageTransition from '@/web/components/New/PageTransition' +import TrackList from '@/web/components/New/TrackList' +import player from '@/web/states/player' +import toast from 'react-hot-toast' +import { useSnapshot } from 'valtio' +import useArtistAlbums from '@/web/api/hooks/useArtistAlbums' +import { css, cx } from '@emotion/css' +import CoverRow from '@/web/components/New/CoverRow' +import { useCallback, useMemo } from 'react' +import MoreByArtist from './MoreByArtist' +import Header from './Header' + +const Album = () => { + const params = useParams() + const { data: album } = useAlbum({ + id: Number(params.id), + }) + + const { data: tracks } = useTracks({ + ids: album?.songs?.map(track => track.id) ?? [], + }) + + const onPlay = useCallback( + async (trackID: number | null = null) => { + if (!album?.album?.id) { + toast('无法播放专辑,该专辑不存在') + return + } + player.playAlbum(album.album.id, trackID) + }, + [album?.album?.id] + ) + + return ( + +
+ + + + {/* Page padding */} +
+ + ) +} + +export default Album diff --git a/packages/web/pages/New/Album/Header.tsx b/packages/web/pages/New/Album/Header.tsx new file mode 100644 index 0000000..e9a0455 --- /dev/null +++ b/packages/web/pages/New/Album/Header.tsx @@ -0,0 +1,107 @@ +import useAlbum from '@/web/api/hooks/useAlbum' +import useUserAlbums, { + useMutationLikeAAlbum, +} from '@/web/api/hooks/useUserAlbums' +import Icon from '@/web/components/Icon' +import TrackListHeader from '@/web/components/New/TrackListHeader' +import useAppleMusicAlbum from '@/web/hooks/useAppleMusicAlbum' +import useVideoCover from '@/web/hooks/useVideoCover' +import player from '@/web/states/player' +import { formatDuration } from '@/web/utils/common' +import dayjs from 'dayjs' +import { useMemo } from 'react' +import toast from 'react-hot-toast' +import { useParams } from 'react-router-dom' + +const Header = () => { + const params = useParams() + const { data: userLikedAlbums } = useUserAlbums() + + const { data: albumRaw } = useAlbum({ + id: Number(params.id), + }) + const album = useMemo(() => albumRaw?.album, [albumRaw]) + + const { data: albumFromApple, isLoading: isLoadingAlbumFromApple } = + useAppleMusicAlbum({ + id: album?.id, + name: album?.name, + artist: album?.artist.name, + }) + + const { data: videoCoverFromRemote } = useVideoCover({ + id: album?.id, + name: album?.name, + artist: album?.artist.name, + enabled: !window.env?.isElectron, + }) + + // For + const cover = album?.picUrl + const videoCover = + albumFromApple?.attributes?.editorialVideo?.motionSquareVideo1x1?.video || + videoCoverFromRemote?.video + + // For + const title = album?.name + const creatorName = album?.artist.name + const creatorLink = `/artist/${album?.artist.id}` + const description = isLoadingAlbumFromApple + ? '' + : albumFromApple?.attributes?.editorialNotes?.standard || album?.description + const extraInfo = useMemo(() => { + const duration = album?.songs?.reduce((acc, cur) => acc + cur.dt, 0) || 0 + const albumDuration = formatDuration(duration, 'en', 'hh[hr] mm[min]') + return ( + <> + {album?.mark === 1056768 && ( + + )}{' '} + {dayjs(album?.publishTime || 0).year()} · {album?.songs.length} tracks,{' '} + {albumDuration} + + ) + }, [album]) + + // For + const isLiked = useMemo(() => { + const id = Number(params.id) + if (!id) return false + return !!userLikedAlbums?.data.find(item => item.id === id) + }, [params.id, userLikedAlbums?.data]) + + const onPlay = async (trackID: number | null = null) => { + if (!album?.id) { + toast('无法播放专辑,该专辑不存在') + return + } + player.playAlbum(album.id, trackID) + } + + const likeAAlbum = useMutationLikeAAlbum() + const onLike = async () => { + likeAAlbum.mutateAsync(album?.id || Number(params.id)) + } + + return ( + + ) +} + +export default Header diff --git a/packages/web/pages/New/Album.tsx b/packages/web/pages/New/Album/MoreByArtist.tsx similarity index 69% rename from packages/web/pages/New/Album.tsx rename to packages/web/pages/New/Album/MoreByArtist.tsx index 259fa2a..776d8c0 100644 --- a/packages/web/pages/New/Album.tsx +++ b/packages/web/pages/New/Album/MoreByArtist.tsx @@ -11,7 +11,6 @@ import useArtistAlbums from '@/web/api/hooks/useArtistAlbums' import { css, cx } from '@emotion/css' import CoverRow from '@/web/components/New/CoverRow' import { useMemo } from 'react' -import 'plyr-react/plyr.css' const MoreByArtist = ({ album }: { album?: Album }) => { const { data: albums } = useArtistAlbums({ @@ -84,48 +83,4 @@ const MoreByArtist = ({ album }: { album?: Album }) => { ) } -const Album = () => { - const params = useParams() - const { data: album } = useAlbum({ - id: Number(params.id), - }) - - const { data: tracks } = useTracks({ - ids: album?.songs?.map(track => track.id) ?? [], - }) - - const playerSnapshot = useSnapshot(player) - - const onPlay = async (trackID: number | null = null) => { - if (!album?.album.id) { - toast('无法播放专辑,该专辑不存在') - return - } - if ( - playerSnapshot.trackListSource?.type === 'album' && - playerSnapshot.trackListSource?.id === album.album.id - ) { - await player.playTrack(trackID ?? album.songs[0].id) - return - } - await player.playAlbum(album.album.id, trackID) - } - - return ( - - - - - - ) -} - -export default Album +export default MoreByArtist diff --git a/packages/web/pages/New/Album/index.tsx b/packages/web/pages/New/Album/index.tsx new file mode 100644 index 0000000..3edbac8 --- /dev/null +++ b/packages/web/pages/New/Album/index.tsx @@ -0,0 +1,2 @@ +import Album from './Album' +export default Album diff --git a/packages/web/pages/New/Artist/Artist.tsx b/packages/web/pages/New/Artist/Artist.tsx index f2d678d..bb39b8b 100644 --- a/packages/web/pages/New/Artist/Artist.tsx +++ b/packages/web/pages/New/Artist/Artist.tsx @@ -5,6 +5,7 @@ import Header from './Header' import Popular from './Popular' import ArtistAlbum from './ArtistAlbums' import FansAlsoLike from './FansAlsoLike' +import ArtistMVs from './ArtistMVs' const Artist = () => { const params = useParams() @@ -17,13 +18,16 @@ const Artist = () => {
+ {/* Dividing line */}
- - + + + {/* Page padding */} +
) } diff --git a/packages/web/pages/New/Artist/ArtistAlbums.tsx b/packages/web/pages/New/Artist/ArtistAlbums.tsx index 38a4f03..b5863a6 100644 --- a/packages/web/pages/New/Artist/ArtistAlbums.tsx +++ b/packages/web/pages/New/Artist/ArtistAlbums.tsx @@ -1,5 +1,6 @@ import useArtistAlbums from '@/web/api/hooks/useArtistAlbums' import CoverRow from '@/web/components/New/CoverRow' +import React from 'react' import { useMemo } from 'react' import { useParams } from 'react-router-dom' @@ -11,7 +12,18 @@ const ArtistAlbum = () => { limit: 1000, }) - const albums = useMemo(() => albumsRaw?.hotAlbums, [albumsRaw?.hotAlbums]) + const pages = useMemo(() => { + const pages: Album[][] = [] + albumsRaw?.hotAlbums.forEach((album, index) => { + const pageNo = Math.floor(index / 12) + if (!pages[pageNo]) { + pages[pageNo] = [album] + } else { + pages[pageNo].push(album) + } + }) + return pages + }, [albumsRaw?.hotAlbums]) return (
@@ -19,9 +31,19 @@ const ArtistAlbum = () => { Albums
- +
+ {pages.map((page, index) => ( + + ))} +
) } -export default ArtistAlbum +const memoized = React.memo(ArtistAlbum) +memoized.displayName = 'ArtistAlbum' +export default memoized diff --git a/packages/web/pages/New/Artist/ArtistMVs.tsx b/packages/web/pages/New/Artist/ArtistMVs.tsx new file mode 100644 index 0000000..bfd7060 --- /dev/null +++ b/packages/web/pages/New/Artist/ArtistMVs.tsx @@ -0,0 +1,32 @@ +import { useNavigate, useParams } from 'react-router-dom' +import useArtistMV from '@/web/api/hooks/useArtistMV' + +const ArtistMVs = () => { + const params = useParams() + const navigate = useNavigate() + const { data: videos } = useArtistMV({ id: Number(params.id) || 0 }) + + return ( +
+
+ MV +
+ +
+ {videos?.mvs?.slice(0, 6)?.map(video => ( +
navigate(`/mv/${video.id}`)}> + +
+ {video.name} +
+
+ ))} +
+
+ ) +} + +export default ArtistMVs diff --git a/packages/web/pages/New/Artist/FansAlsoLike.tsx b/packages/web/pages/New/Artist/FansAlsoLike.tsx index 46e25d6..bc49978 100644 --- a/packages/web/pages/New/Artist/FansAlsoLike.tsx +++ b/packages/web/pages/New/Artist/FansAlsoLike.tsx @@ -4,16 +4,22 @@ import { useParams } from 'react-router-dom' const FansAlsoLike = () => { const params = useParams() - const { data: artists } = useSimilarArtists({ id: Number(params.id) || 0 }) + const { data: artists, isLoading } = useSimilarArtists({ + id: Number(params.id) || 0, + }) return ( -
-
- Fans Also Like -
+ <> + {(isLoading || artists?.artists) && ( +
+
+ Fans Also Like +
- -
+ +
+ )} + ) } diff --git a/packages/web/pages/New/Artist/Header/Actions.tsx b/packages/web/pages/New/Artist/Header/Actions.tsx index 3815bb7..d53d7d1 100644 --- a/packages/web/pages/New/Artist/Header/Actions.tsx +++ b/packages/web/pages/New/Artist/Header/Actions.tsx @@ -1,11 +1,44 @@ +import useUserArtists, { + useMutationLikeAArtist, +} from '@/web/api/hooks/useUserArtists' +import Icon from '@/web/components/Icon' +import player from '@/web/states/player' +import { useParams } from 'react-router-dom' + const Actions = () => { + const { data: likedArtists } = useUserArtists() + const params = useParams() + const id = Number(params.id) || 0 + const isLiked = !!likedArtists?.data?.find(artist => artist.id === id) + const likeArtist = useMutationLikeAArtist() + return (
- - + {/* Menu */} + + + {/* Like */} +
- + + {/* Listen */} +
) } diff --git a/packages/web/pages/New/Artist/Header/ArtistInfo.tsx b/packages/web/pages/New/Artist/Header/ArtistInfo.tsx index 88749fc..9ed67ef 100644 --- a/packages/web/pages/New/Artist/Header/ArtistInfo.tsx +++ b/packages/web/pages/New/Artist/Header/ArtistInfo.tsx @@ -1,5 +1,6 @@ import useIsMobile from '@/web/hooks/useIsMobile' import useAppleMusicArtist from '@/web/hooks/useAppleMusicArtist' +import { cx, css } from '@emotion/css' const ArtistInfo = ({ artist }: { artist?: Artist }) => { const isMobile = useIsMobile() @@ -11,20 +12,27 @@ const ArtistInfo = ({ artist }: { artist?: Artist }) => { return (
-
+
{artist?.name}
-
+
Artist
-
+
{artist?.musicSize} Tracks · {artist?.albumSize} Albums ·{' '} {artist?.mvSize} Videos
{/* Description */} {!isMobile && !isLoadingArtistFromApple && ( -
+
{artistFromApple?.attributes?.artistBio || artist?.briefDesc}
)} diff --git a/packages/web/pages/New/Artist/Header/Cover.tsx b/packages/web/pages/New/Artist/Header/Cover.tsx new file mode 100644 index 0000000..fea0b69 --- /dev/null +++ b/packages/web/pages/New/Artist/Header/Cover.tsx @@ -0,0 +1,101 @@ +import { isIOS, isSafari, resizeImage } from '@/web/utils/common' +import Image from '@/web/components/New/Image' +import { cx, css } from '@emotion/css' +import useAppleMusicArtist from '@/web/hooks/useAppleMusicArtist' +import { useEffect, useRef } from 'react' +import Hls from 'hls.js' +import { motion } from 'framer-motion' +import uiStates from '@/web/states/uiStates' + +const VideoCover = ({ source }: { source?: string }) => { + const ref = useRef(null) + const hls = useRef(new Hls()) + + useEffect(() => { + if (source && Hls.isSupported()) { + const video = document.querySelector('#video-cover') as HTMLVideoElement + hls.current.loadSource(source) + hls.current.attachMedia(video) + } + }, [source]) + + return ( +
+
+ ) +} + +const Cover = ({ artist }: { artist?: Artist }) => { + const { data: artistFromApple, isLoading: isLoadingArtistFromApple } = + useAppleMusicArtist({ + id: artist?.id, + name: artist?.name, + }) + + const video = + artistFromApple?.attributes?.editorialVideo?.motionArtistSquare1x1?.video + const cover = isLoadingArtistFromApple + ? '' + : artistFromApple?.attributes?.artwork?.url || artist?.img1v1Url + + useEffect(() => { + if (cover) uiStates.blurBackgroundImage = cover + }, [cover]) + + return ( + <> +
+ + + {video && ( + + {isSafari ? ( + + ) : ( + + )} + + )} +
+ + ) +} + +export default Cover diff --git a/packages/web/pages/New/Artist/Header/Header.tsx b/packages/web/pages/New/Artist/Header/Header.tsx index 12a4b92..637e488 100644 --- a/packages/web/pages/New/Artist/Header/Header.tsx +++ b/packages/web/pages/New/Artist/Header/Header.tsx @@ -1,19 +1,10 @@ -import { resizeImage } from '@/web/utils/common' import { cx, css } from '@emotion/css' -import Image from '@/web/components/New/Image' import { breakpoint as bp } from '@/web/utils/const' -import BlurBackground from '@/web/components/New/BlurBackground' import ArtistInfo from './ArtistInfo' import Actions from './Actions' import LatestRelease from './LatestRelease' -import useAppleMusicArtist from '@/web/hooks/useAppleMusicArtist' - +import Cover from "./Cover" const Header = ({ artist }: { artist?: Artist }) => { - const { data: artistFromApple, isLoading: isLoadingArtistFromApple } = - useAppleMusicArtist({ - id: artist?.id, - name: artist?.name, - }) return (
{ ` )} > - - - +
{ const params = useParams() @@ -54,30 +55,40 @@ const Album = () => { } const Video = () => { + const params = useParams() + const { data: videos } = useArtistMV({ id: Number(params.id) || 0 }) + const video = videos?.mvs?.[0] + const navigate = useNavigate() + return ( -
- -
-
- Swedish House Mafia & The Weeknd Live at C... + <> + {video && ( +
navigate(`/mv/${video.id}`)} + > + +
+
+ {video.name} +
+
MV
+
+ {dayjs(video.publishTime).format('MMM DD, YYYY')} +
+
-
- {dayjs().format('MMM DD, YYYY')} -
-
-
+ )} + ) } diff --git a/packages/web/pages/New/Browse.tsx b/packages/web/pages/New/Browse.tsx index ce13b1d..0a99971 100644 --- a/packages/web/pages/New/Browse.tsx +++ b/packages/web/pages/New/Browse.tsx @@ -5,7 +5,7 @@ import { } from '@/web/api/playlist' import { PlaylistApiNames } from '@/shared/api/Playlists' import { useState } from 'react' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' import CoverRowVirtual from '@/web/components/New/CoverRowVirtual' import PageTransition from '@/web/components/New/PageTransition' import { playerWidth, topbarHeight } from '@/web/utils/const' @@ -20,31 +20,27 @@ const reactQueryOptions = { } const Recommend = () => { - const { data: dailyRecommendPlaylists } = useQuery( - PlaylistApiNames.FetchDailyRecommendPlaylists, + const { data: dailyRecommendPlaylists, isLoading: isLoadingDaily } = useQuery( + [PlaylistApiNames.FetchDailyRecommendPlaylists], () => fetchDailyRecommendPlaylists(), reactQueryOptions ) - const { data: recommendedPlaylists } = useQuery( + const { data: recommendedPlaylists, isLoading: isLoading } = useQuery( [PlaylistApiNames.FetchRecommendedPlaylists, { limit: 200 }], () => fetchRecommendedPlaylists({ limit: 200 }), reactQueryOptions ) - const playlists = [ - ...(dailyRecommendPlaylists?.recommend || []), - ...(recommendedPlaylists?.result || []), - ] + const playlists = + isLoadingDaily || isLoading + ? [] + : [ + ...(dailyRecommendPlaylists?.recommend || []), + ...(recommendedPlaylists?.result || []), + ] - // return ( - // - // ) + return - return + // return } const All = () => { @@ -66,27 +62,29 @@ const Browse = () => { return ( - {/* Topbar background */} - +
+ {/* Topbar background */} + - setActive(category)} - className='sticky top-0 z-10 mt-2.5 px-2.5 lg:mt-0 lg:px-0' - /> + setActive(category)} + className='absolute top-0 z-10 mt-2.5 px-2.5 lg:mt-0 lg:px-0' + /> -
- {categories.find(c => c.id === active)?.component} +
+ {categories.find(c => c.id === active)?.component} +
) diff --git a/packages/web/pages/New/Discover.tsx b/packages/web/pages/New/Discover.tsx index 631d96b..44265eb 100644 --- a/packages/web/pages/New/Discover.tsx +++ b/packages/web/pages/New/Discover.tsx @@ -8,7 +8,7 @@ import { fetchTracksWithReactQuery } from '@/web/api/hooks/useTracks' import { useEffect, useState } from 'react' import { sampleSize } from 'lodash-es' import { FetchPlaylistResponse } from '@/shared/api/Playlists' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' interface DiscoverAlbum { id: number diff --git a/packages/web/pages/New/MV.tsx b/packages/web/pages/New/MV.tsx new file mode 100644 index 0000000..40bdaa8 --- /dev/null +++ b/packages/web/pages/New/MV.tsx @@ -0,0 +1,62 @@ +import PageTransition from '@/web/components/New/PageTransition' +import useMV, { useMVUrl } from '@/web/api/hooks/useMV' +import { useParams } from 'react-router-dom' +import Plyr, { PlyrOptions, PlyrSource } from 'plyr-react' +import 'plyr-react/plyr.css' +import { useMemo } from 'react' +import { css, cx } from '@emotion/css' + +const plyrStyle = css` + --plyr-color-main: rgb(152 208 11); + --plyr-video-control-background-hover: rgba(255, 255, 255, 0.3); + --plyr-control-radius: 8px; + --plyr-range-fill-background: white; + button[data-plyr='play']:not(.plyr__controls__item) { + --plyr-video-control-background-hover: var(--plyr-color-main); + } +` + +const plyrOptions: PlyrOptions = { + settings: [], + controls: [ + 'play-large', + 'play', + 'progress', + 'current-time', + 'mute', + 'volume', + 'fullscreen', + ], + resetOnEnd: true, + ratio: '16:9', +} + +const MV = () => { + const params = useParams() + const { data: mv } = useMV({ mvid: Number(params.id) || 0 }) + const { data: mvUrl } = useMVUrl({ id: Number(params.id) || 0 }) + const source: PlyrSource = useMemo( + () => ({ + type: 'video', + sources: [ + { + src: mvUrl?.data?.url || '', + }, + ], + poster: mv?.data.cover, + title: mv?.data.name, + }), + [mv?.data.cover, mv?.data.name, mvUrl?.data?.url] + ) + + return ( + +
{mv?.data.name}
+
+ {mvUrl && } +
+
+ ) +} + +export default MV diff --git a/packages/web/pages/New/My/Collections.tsx b/packages/web/pages/New/My/Collections.tsx index ab941f5..b5b01ec 100644 --- a/packages/web/pages/New/My/Collections.tsx +++ b/packages/web/pages/New/My/Collections.tsx @@ -7,6 +7,7 @@ import useUserPlaylists from '@/web/api/hooks/useUserPlaylists' import useUserAlbums from '@/web/api/hooks/useUserAlbums' import { useSnapshot } from 'valtio' import uiStates from '@/web/states/uiStates' +import ArtistRow from '@/web/components/New/ArtistRow' const tabs = [ { @@ -30,17 +31,21 @@ const tabs = [ const Albums = () => { const { data: albums } = useUserAlbums() - return + return } const Playlists = () => { const { data: playlists } = useUserPlaylists() const p = useMemo(() => playlists?.playlist?.slice(1), [playlists]) - return + return +} + +const Artists = () => { + const { data: artists } = useUserArtists() + return } const Collections = () => { - // const { data: artists } = useUserArtists() const { librarySelectedTab: selectedTab } = useSnapshot(uiStates) const setSelectedTab = ( id: 'playlists' | 'albums' | 'artists' | 'videos' @@ -56,8 +61,11 @@ const Collections = () => { onChange={(id: string) => setSelectedTab(id)} className='px-2.5 lg:px-0' /> - {selectedTab === 'albums' && } - {selectedTab === 'playlists' && } +
+ {selectedTab === 'albums' && } + {selectedTab === 'playlists' && } + {selectedTab === 'artists' && } +
) } diff --git a/packages/web/pages/New/My/PlayLikedSongsCard.tsx b/packages/web/pages/New/My/PlayLikedSongsCard.tsx index 1302c7c..7bbf82d 100644 --- a/packages/web/pages/New/My/PlayLikedSongsCard.tsx +++ b/packages/web/pages/New/My/PlayLikedSongsCard.tsx @@ -12,9 +12,11 @@ import { lyricParser } from '@/web/utils/lyric' import Image from '@/web/components/New/Image' import { resizeImage } from '@/web/utils/common' import { breakpoint as bp } from '@/web/utils/const' +import useUser from '@/web/api/hooks/useUser' const Lyrics = ({ tracksIDs }: { tracksIDs: number[] }) => { const [id, setId] = useState(0) + const { data: user } = useUser() useEffect(() => { if (id === 0) { @@ -37,7 +39,7 @@ const Lyrics = ({ tracksIDs }: { tracksIDs: number[] }) => { return (
{ ` )} > +
+ {user?.profile?.nickname}'S LIKED TRACKS +
{lyricLines.map((line, index) => ( -
{line}
+
+ {line} +
))}
) @@ -136,7 +146,7 @@ const PlayLikedSongsCard = () => { navigate(`/playlist/${likedSongsPlaylist?.playlist.id}`) } className={cx( - 'flex items-center justify-center rounded-full bg-white/10 text-night-400', + 'flex items-center justify-center rounded-full bg-white/10 text-night-400 transition duration-400 hover:bg-white/20 hover:text-neutral-300', css` padding: 15.5px; ` diff --git a/packages/web/pages/New/Playlist.tsx b/packages/web/pages/New/Playlist.tsx deleted file mode 100644 index 5305c1a..0000000 --- a/packages/web/pages/New/Playlist.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import TrackListHeader from '@/web/components/New/TrackListHeader' -import { NavLink, useParams } from 'react-router-dom' -import PageTransition from '@/web/components/New/PageTransition' -import TrackList from '@/web/components/New/TrackList' -import player from '@/web/states/player' -import toast from 'react-hot-toast' -import { useSnapshot } from 'valtio' -import { memo, useEffect, useMemo } from 'react' -import usePlaylist from '@/web/api/hooks/usePlaylist' -import useTracksInfinite from '@/web/api/hooks/useTracksInfinite' - -const Playlist = () => { - const params = useParams() - const { data: playlist, isLoading } = usePlaylist({ - id: Number(params.id), - }) - - const playerSnapshot = useSnapshot(player) - const onPlay = async (trackID: number | null = null) => { - if (!playlist?.playlist.id) { - toast('无法播放歌单,该歌单不存在') - return - } - - if ( - playerSnapshot.trackListSource?.type === 'playlist' && - playerSnapshot.trackListSource?.id === playlist.playlist.id && - playlist?.playlist?.trackIds?.[0].id - ) { - await player.playTrack(trackID ?? playlist.playlist.trackIds[0].id) - return - } - await player.playPlaylist(playlist.playlist.id, trackID) - } - - return ( - - - - - ) -} - -export default Playlist diff --git a/packages/web/pages/New/Playlist/Header.tsx b/packages/web/pages/New/Playlist/Header.tsx new file mode 100644 index 0000000..dbf380a --- /dev/null +++ b/packages/web/pages/New/Playlist/Header.tsx @@ -0,0 +1,75 @@ +import usePlaylist from '@/web/api/hooks/usePlaylist' +import useUser from '@/web/api/hooks/useUser' +import useUserPlaylists, { + useMutationLikeAPlaylist, +} from '@/web/api/hooks/useUserPlaylists' +import TrackListHeader from '@/web/components/New/TrackListHeader' +import player from '@/web/states/player' +import { formatDate } from '@/web/utils/common' +import { useMemo } from 'react' +import { useParams } from 'react-router-dom' + +const Header = () => { + const params = useParams() + + const { data: playlistRaw, isLoading } = usePlaylist({ + id: Number(params.id), + }) + const { data: user } = useUser() + + const { data: userLikedPlaylists } = useUserPlaylists() + + const playlist = playlistRaw?.playlist + + // For + const cover = playlist?.coverImgUrl || playlist?.picUrl + + // For + const title = playlist?.name + const creatorName = playlist?.creator?.nickname + const creatorLink = undefined // TODO: 链接到用户页面 + const description = playlist?.description || '' + const extraInfo = useMemo(() => { + return ( + <> + Updated at {formatDate(playlist?.updateTime || 0, 'en')} ·{' '} + {playlist?.trackCount} tracks + + ) + }, [playlist]) + + // For + const isLiked = useMemo(() => { + const id = Number(params.id) + if (!id) return false + return !!userLikedPlaylists?.playlist.find(p => p.id === id) + }, [params.id, userLikedPlaylists?.playlist]) + + const onPlay = async (trackID: number | null = null) => { + await player.playPlaylist(playlist?.id, trackID) + } + + const likeAPlaylist = useMutationLikeAPlaylist() + const onLike = async () => { + likeAPlaylist.mutateAsync(playlist?.id || Number(params.id)) + } + + return ( + + ) +} + +export default Header diff --git a/packages/web/pages/New/Playlist/Playlist.tsx b/packages/web/pages/New/Playlist/Playlist.tsx new file mode 100644 index 0000000..43a655e --- /dev/null +++ b/packages/web/pages/New/Playlist/Playlist.tsx @@ -0,0 +1,30 @@ +import { useParams } from 'react-router-dom' +import PageTransition from '@/web/components/New/PageTransition' +import TrackList from '@/web/components/New/TrackList' +import player from '@/web/states/player' +import usePlaylist from '@/web/api/hooks/usePlaylist' +import Header from './Header' + +const Playlist = () => { + const params = useParams() + const { data: playlist } = usePlaylist({ + id: Number(params.id), + }) + + const onPlay = async (trackID: number | null = null) => { + await player.playPlaylist(playlist?.playlist?.id, trackID) + } + + return ( + +
+ + + ) +} + +export default Playlist diff --git a/packages/web/pages/New/Playlist/index.tsx b/packages/web/pages/New/Playlist/index.tsx new file mode 100644 index 0000000..522a780 --- /dev/null +++ b/packages/web/pages/New/Playlist/index.tsx @@ -0,0 +1,3 @@ +import Playlist from './Playlist' + +export default Playlist diff --git a/packages/web/pages/Search/Search.tsx b/packages/web/pages/Search/Search.tsx index d59e638..18f0631 100644 --- a/packages/web/pages/Search/Search.tsx +++ b/packages/web/pages/Search/Search.tsx @@ -7,7 +7,7 @@ import { SearchTypes, SearchApiNames } from '@/shared/api/Search' import dayjs from 'dayjs' import { useMemo, useCallback } from 'react' import toast from 'react-hot-toast' -import { useQuery } from 'react-query' +import { useQuery } from '@tanstack/react-query' import { useNavigate, useParams } from 'react-router-dom' const Artists = ({ artists }: { artists: Artist[] }) => { diff --git a/packages/web/states/persistedUiStates.ts b/packages/web/states/persistedUiStates.ts index 123ba83..26bfebf 100644 --- a/packages/web/states/persistedUiStates.ts +++ b/packages/web/states/persistedUiStates.ts @@ -1,19 +1,35 @@ +import { merge } from 'lodash-es' import { proxy, subscribe } from 'valtio' interface PersistedUiStates { loginPhoneCountryCode: string loginType: 'phone' | 'email' | 'qrCode' + minimizePlayer: boolean } const initPersistedUiStates: PersistedUiStates = { loginPhoneCountryCode: '+86', loginType: 'qrCode', + minimizePlayer: false, } -const persistedUiStates = proxy(initPersistedUiStates) +const STORAGE_KEY = 'persistedUiStates' +const statesInStorage = localStorage.getItem(STORAGE_KEY) +let sates = {} +if (statesInStorage) { + try { + sates = JSON.parse(statesInStorage) + } catch { + // ignore + } +} + +const persistedUiStates = proxy( + merge(initPersistedUiStates, sates) +) subscribe(persistedUiStates, () => { - localStorage.setItem('persistedUiStates', JSON.stringify(persistedUiStates)) + localStorage.setItem(STORAGE_KEY, JSON.stringify(persistedUiStates)) }) export default persistedUiStates diff --git a/packages/web/states/settings.ts b/packages/web/states/settings.ts index bc2ee42..b1ad185 100644 --- a/packages/web/states/settings.ts +++ b/packages/web/states/settings.ts @@ -35,19 +35,22 @@ const initSettings: Settings = { }, } -const settingsInLocalStorage = localStorage.getItem('settings') -const settings = proxy( - merge( - initSettings, - settingsInLocalStorage ? JSON.parse(settingsInLocalStorage) : {} - ) -) +const STORAGE_KEY = 'settings' +const statesInStorageString = localStorage.getItem(STORAGE_KEY) +let statesInStorage = {} +if (statesInStorageString) { + try { + statesInStorage = JSON.parse(statesInStorageString) + } catch { + // ignore + } +} + +const settings = proxy(merge(initSettings, statesInStorage)) -subscribe(settings, () => { - localStorage.setItem('settings', JSON.stringify(settings)) -}) subscribe(settings, () => { window.ipcRenderer?.send(IpcChannels.SyncSettings, settings) + localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)) }) export default settings diff --git a/packages/web/states/uiStates.ts b/packages/web/states/uiStates.ts index eb5b843..2aca117 100644 --- a/packages/web/states/uiStates.ts +++ b/packages/web/states/uiStates.ts @@ -1,3 +1,4 @@ +import { IpcChannels } from '@/shared/IpcChannels' import { proxy } from 'valtio' interface UIStates { @@ -6,6 +7,8 @@ interface UIStates { hideTopbarBackground: boolean librarySelectedTab: 'playlists' | 'albums' | 'artists' | 'videos' mobileShowPlayingNext: boolean + blurBackgroundImage: string | null + fullscreen: boolean } const initUIStates: UIStates = { @@ -14,6 +17,8 @@ const initUIStates: UIStates = { hideTopbarBackground: false, librarySelectedTab: 'playlists', mobileShowPlayingNext: false, + blurBackgroundImage: null, + fullscreen: window.ipcRenderer?.sendSync(IpcChannels.IsMaximized) || false, } export default proxy(initUIStates) diff --git a/packages/web/tailwind.config.js b/packages/web/tailwind.config.js index 91461da..6862c93 100644 --- a/packages/web/tailwind.config.js +++ b/packages/web/tailwind.config.js @@ -90,6 +90,9 @@ module.exports = { margin: { 7.5: '1.875rem', }, + transitionDuration: { + 400: '400ms', + }, }, }, variants: {}, diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json index 6f1abe7..1226ccc 100644 --- a/packages/web/tsconfig.json +++ b/packages/web/tsconfig.json @@ -15,9 +15,9 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", - "baseUrl": "./", + "baseUrl": "../", "paths": { - "@/*": ["../*"] + "@/*": ["./*"] } }, "include": ["./**/*.ts", "./**/*.tsx", "../shared/**/*.ts"] diff --git a/packages/web/utils/common.ts b/packages/web/utils/common.ts index 4555272..a7cedc4 100644 --- a/packages/web/utils/common.ts +++ b/packages/web/utils/common.ts @@ -6,7 +6,7 @@ import { average } from 'color.js' import { colord } from 'colord' /** - * @description 调整网易云封面图片大小 + * @description 调整网易云和苹果音乐封面图片大小 * @param {string} url 封面图片URL * @param {'xs'|'sm'|'md'|'lg'} size - 大小,值对应为 128px | 256px | 512px | 1024px */ @@ -173,3 +173,5 @@ export const isPWA = (navigator as any).standalone || window.matchMedia('(display-mode: standalone)').matches export const isIosPwa = isIOS && isPWA && isSafari + +export const sleep = (ms: number) => new Promise(r => setTimeout(r, ms)) diff --git a/packages/web/utils/const.ts b/packages/web/utils/const.ts index 4cbccd9..9af7bcb 100644 --- a/packages/web/utils/const.ts +++ b/packages/web/utils/const.ts @@ -10,5 +10,6 @@ export const breakpoint = { '2xl': '@media (min-width: 1536px)', } +export const titleBarHeight = 32 // 桌面端标题栏高度 (px) export const topbarHeight = 132 // 桌面端顶栏高度 (px) export const playerWidth = 318 // 桌面端播放器宽度 (px) diff --git a/packages/web/utils/player.ts b/packages/web/utils/player.ts index ed64a0e..ca12ef7 100644 --- a/packages/web/utils/player.ts +++ b/packages/web/utils/player.ts @@ -15,16 +15,22 @@ import { IpcChannels } from '@/shared/IpcChannels' import { RepeatMode } from '@/shared/playerDataTypes' import toast from 'react-hot-toast' import { scrobble } from '@/web/api/user' +import { fetchArtistWithReactQuery } from '../api/hooks/useArtist' type TrackID = number export enum TrackListSourceType { Album = 'album', Playlist = 'playlist', + Artist = 'artist', } interface TrackListSource { type: TrackListSourceType id: number } +interface RemoteDevice { + protocol: 'airplay' | 'chromecast' + id: string +} export enum Mode { TrackList = 'trackList', FM = 'fm', @@ -55,6 +61,7 @@ export class Player { fmTrackList: TrackID[] = [] shuffle: boolean = false fmTrack: Track | null = null + remoteDevice: RemoteDevice | null = null init(params: { [key: string]: any }) { if (params._track) this._track = params._track @@ -70,7 +77,7 @@ export class Player { if (params.fmTrack) this.fmTrack = params.fmTrack this.state = State.Ready - this._playAudio(false) // just load the audio, not play + if (this.trackID) this._playAudio(false) // just load the audio, not play this._initFM() this._initMediaSession() @@ -165,6 +172,10 @@ export class Player { window.ipcRenderer?.send(IpcChannels.Repeat, { mode: this._repeatMode }) } + get _isAirplay() { + return this.remoteDevice?.protocol === 'airplay' + } + private async _initFM() { if (this.fmTrackList.length === 0) await this._loadMoreFMTracks() @@ -182,9 +193,30 @@ export class Player { } private async _setupProgressInterval() { - this._progressInterval = setInterval(() => { - if (this.state === State.Playing) this._progress = _howler.seek() - }, 1000) + if (this.remoteDevice === null) { + // Howler + this._progressInterval = setInterval(() => { + if (this.state === State.Playing) this._progress = _howler.seek() + }, 1000) + } else if (this._isAirplay) { + // Airplay + let isFetchAirplayPlayingInfo = false + this._progressInterval = setInterval(async () => { + if (isFetchAirplayPlayingInfo) return + + isFetchAirplayPlayingInfo = true + + const playingInfo = await window?.ipcRenderer?.invoke( + 'airplay-get-playing', + { deviceID: this.remoteDevice?.id } + ) + if (playingInfo) { + this._progress = playingInfo.position || 0 + } + + isFetchAirplayPlayingInfo = false + }, 1000) + } } private async _scrobble() { @@ -255,6 +287,19 @@ export class Player { return } if (this.trackID !== id) return + if (this._isAirplay) { + this._playAudioViaAirplay(audio) + return + } else { + this._playAudioViaHowler(audio, id, autoplay) + } + } + + private async _playAudioViaHowler( + audio: string, + id: number, + autoplay: boolean = true + ) { Howler.unload() const url = audio.includes('?') ? `${audio}&dash-id=${id}` @@ -282,6 +327,18 @@ export class Player { } } + private async _playAudioViaAirplay(audio: string) { + if (!this._isAirplay) { + console.log('No airplay device selected') + return + } + const result = await window.ipcRenderer?.invoke('airplay-play-url', { + deviceID: this.remoteDevice?.id, + url: audio, + }) + console.log(result) + } + private _howlerOnEndCallback() { if (this.mode !== Mode.FM && this.repeatMode === RepeatMode.One) { _howler.seek(0) @@ -432,7 +489,11 @@ export class Player { * @param {number} id * @param {null|number=} autoPlayTrackID */ - async playPlaylist(id: number, autoPlayTrackID?: null | number) { + async playPlaylist(id: number | undefined, autoPlayTrackID?: null | number) { + if (!id) { + toast.error('无法播放: 歌单不存在') + return + } this._setStateToLoading() const playlist = await fetchPlaylistWithReactQuery({ id }) if (!playlist?.playlist?.trackIds?.length) return @@ -447,7 +508,7 @@ export class Player { } /** - * Play am album + * Play an album * @param {number} id * @param {null|number=} autoPlayTrackID */ @@ -465,6 +526,28 @@ export class Player { ) } + /** + * Listen artist's popular tracks + * @param {number} id + * @param {null|number=} autoPlayTrackID + */ + async playArtistPopularTracks(id: number, autoPlayTrackID?: null | number) { + this._setStateToLoading() + const artist = await fetchArtistWithReactQuery({ id }) + if (!artist?.hotSongs.length) { + toast('无法播放: 没有热门歌曲') + return + } + this.trackListSource = { + type: TrackListSourceType.Artist, + id, + } + this.playAList( + artist.hotSongs.map(t => t.id), + autoPlayTrackID + ) + } + /** * Play personal fm */ @@ -503,6 +586,21 @@ export class Player { this._playTrack() } + async switchToThisComputer() { + this.remoteDevice = null + clearInterval(this._progressInterval) + this._setupProgressInterval() + } + + async switchToAirplayDevice(deviceID: string) { + this.remoteDevice = { + protocol: 'airplay', + id: deviceID, + } + clearInterval(this._progressInterval) + this._setupProgressInterval() + } + private async _initMediaSession() { console.log('init') if ('mediaSession' in navigator === false) return diff --git a/packages/web/utils/reactQueryClient.ts b/packages/web/utils/reactQueryClient.ts index a0ec171..a4bbb6b 100644 --- a/packages/web/utils/reactQueryClient.ts +++ b/packages/web/utils/reactQueryClient.ts @@ -1,4 +1,4 @@ -import { QueryClient } from 'react-query' +import { QueryClient } from '@tanstack/react-query' const reactQueryClient = new QueryClient({ defaultOptions: { diff --git a/packages/web/utils/request.ts b/packages/web/utils/request.ts index 2717959..2977178 100644 --- a/packages/web/utils/request.ts +++ b/packages/web/utils/request.ts @@ -21,7 +21,7 @@ service.interceptors.request.use((config: AxiosRequestConfig) => { service.interceptors.response.use( (response: AxiosResponse) => { - const res = response //.data + const res = response return res }, (error: AxiosError) => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1f3f0b5..cc30cde 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,6 +16,105 @@ importers: turbo: 1.2.16 typescript: 4.7.3 + packages/desktop: + specifiers: + '@electron/universal': 1.2.1 + '@sentry/electron': ^3.0.7 + '@sentry/node': ^6.19.7 + '@sentry/tracing': ^6.19.7 + '@types/better-sqlite3': ^7.5.0 + '@types/cookie-parser': ^1.4.3 + '@types/express': ^4.17.13 + '@types/express-fileupload': ^1.2.2 + '@typescript-eslint/eslint-plugin': ^5.30.7 + '@typescript-eslint/parser': ^5.30.7 + '@unblockneteasemusic/rust-napi': ^0.3.0 + '@vitejs/plugin-react': ^1.3.1 + '@vitest/ui': ^0.12.10 + axios: ^0.27.2 + better-sqlite3: 7.5.1 + change-case: ^4.1.2 + chromecast-api: ^0.4.0 + compare-versions: ^4.1.3 + connect-history-api-fallback: ^2.0.0 + cookie-parser: ^1.4.6 + cross-env: ^7.0.3 + dotenv: ^16.0.0 + electron: ^19.0.8 + electron-builder: 23.3.1 + electron-devtools-installer: ^3.2.0 + electron-log: ^4.4.8 + electron-rebuild: ^3.2.8 + electron-releases: ^3.1072.0 + electron-store: ^8.0.2 + esbuild: ^0.14.49 + eslint: '*' + express: ^4.18.1 + express-fileupload: ^1.4.0 + fast-folder-size: ^1.7.0 + m3u8-parser: ^4.7.1 + minimist: ^1.2.6 + music-metadata: ^7.12.4 + NeteaseCloudMusicApi: ^4.6.7 + open-cli: ^7.0.1 + ora: ^6.1.2 + picocolors: ^1.0.0 + prettier: '*' + pretty-bytes: ^6.0.0 + typescript: '*' + vitest: ^0.12.10 + wait-on: ^6.0.1 + zx: ^7.0.7 + dependencies: + '@sentry/electron': 3.0.7 + '@sentry/node': 6.19.7 + '@sentry/tracing': 6.19.7 + '@unblockneteasemusic/rust-napi': 0.3.0 + better-sqlite3: 7.5.1 + change-case: 4.1.2 + chromecast-api: 0.4.0 + compare-versions: 4.1.3 + connect-history-api-fallback: 2.0.0 + cookie-parser: 1.4.6 + electron-log: 4.4.8 + electron-store: 8.0.2 + express: 4.18.1 + fast-folder-size: 1.7.0 + m3u8-parser: 4.7.1 + NeteaseCloudMusicApi: 4.6.7 + pretty-bytes: 6.0.0 + zx: 7.0.7 + devDependencies: + '@electron/universal': 1.2.1 + '@types/better-sqlite3': 7.5.0 + '@types/cookie-parser': 1.4.3 + '@types/express': 4.17.13 + '@types/express-fileupload': 1.2.2 + '@typescript-eslint/eslint-plugin': 5.30.7_6wltbjakwuqm7awqswigmiuhd4 + '@typescript-eslint/parser': 5.30.7_he2ccbldppg44uulnyq4rwocfa + '@vitejs/plugin-react': 1.3.2 + '@vitest/ui': 0.12.10 + axios: 0.27.2 + cross-env: 7.0.3 + dotenv: 16.0.1 + electron: 19.0.8 + electron-builder: 23.3.1 + electron-devtools-installer: 3.2.0 + electron-rebuild: 3.2.8 + electron-releases: 3.1072.0 + esbuild: 0.14.49 + eslint: 8.20.0 + express-fileupload: 1.4.0 + minimist: 1.2.6 + music-metadata: 7.12.4 + open-cli: 7.0.1 + ora: 6.1.2 + picocolors: 1.0.0 + prettier: 2.7.1 + typescript: 4.7.4 + vitest: 0.12.10_@vitest+ui@0.12.10 + wait-on: 6.0.1 + packages/electron: specifiers: '@electron/universal': 1.2.1 @@ -25,89 +124,99 @@ importers: '@types/cookie-parser': ^1.4.3 '@types/express': ^4.17.13 '@types/express-fileupload': ^1.2.2 - '@typescript-eslint/eslint-plugin': ^5.27.0 - '@typescript-eslint/parser': ^5.27.0 + '@typescript-eslint/eslint-plugin': ^5.30.7 + '@typescript-eslint/parser': ^5.30.7 '@unblockneteasemusic/rust-napi': ^0.3.0 '@vitejs/plugin-react': ^1.3.1 + '@vitest/ui': ^0.12.10 axios: ^0.27.2 better-sqlite3: 7.5.1 change-case: ^4.1.2 + chromecast-api: ^0.4.0 compare-versions: ^4.1.3 + connect-history-api-fallback: ^2.0.0 cookie-parser: ^1.4.6 cross-env: ^7.0.3 dotenv: ^16.0.0 - electron: ^19.0.3 - electron-builder: ^23.0.3 + electron: ^19.0.8 + electron-builder: 23.3.1 electron-devtools-installer: ^3.2.0 - electron-log: ^4.4.6 - electron-rebuild: ^3.2.7 - electron-releases: ^3.1026.0 - electron-store: ^8.0.1 - esbuild: ^0.14.42 + electron-log: ^4.4.8 + electron-rebuild: ^3.2.8 + electron-releases: ^3.1072.0 + electron-store: ^8.0.2 + esbuild: ^0.14.49 eslint: '*' express: ^4.18.1 express-fileupload: ^1.4.0 fast-folder-size: ^1.7.0 m3u8-parser: ^4.7.1 minimist: ^1.2.6 - music-metadata: ^7.12.3 - NeteaseCloudMusicApi: ^4.6.2 + music-metadata: ^7.12.4 + NeteaseCloudMusicApi: ^4.6.7 open-cli: ^7.0.1 - ora: ^6.1.0 + ora: ^6.1.2 picocolors: ^1.0.0 prettier: '*' pretty-bytes: ^6.0.0 typescript: '*' + vitest: ^0.12.10 wait-on: ^6.0.1 + zx: ^7.0.7 dependencies: '@sentry/node': 6.19.7 '@sentry/tracing': 6.19.7 '@unblockneteasemusic/rust-napi': 0.3.0 better-sqlite3: 7.5.1 change-case: 4.1.2 + chromecast-api: 0.4.0 compare-versions: 4.1.3 + connect-history-api-fallback: 2.0.0 cookie-parser: 1.4.6 - electron-log: 4.4.7 - electron-store: 8.0.1 + electron-log: 4.4.8 + electron-store: 8.0.2 express: 4.18.1 fast-folder-size: 1.7.0 m3u8-parser: 4.7.1 - NeteaseCloudMusicApi: 4.6.2 + NeteaseCloudMusicApi: 4.6.7 pretty-bytes: 6.0.0 + zx: 7.0.7 devDependencies: '@electron/universal': 1.2.1 '@types/better-sqlite3': 7.5.0 '@types/cookie-parser': 1.4.3 '@types/express': 4.17.13 '@types/express-fileupload': 1.2.2 - '@typescript-eslint/eslint-plugin': 5.27.0_kor2e3kwnnzugzo3aovmfcq2la - '@typescript-eslint/parser': 5.27.0_ud6rd4xtew5bv4yhvkvu24pzm4 + '@typescript-eslint/eslint-plugin': 5.30.7_6wltbjakwuqm7awqswigmiuhd4 + '@typescript-eslint/parser': 5.30.7_he2ccbldppg44uulnyq4rwocfa '@vitejs/plugin-react': 1.3.2 + '@vitest/ui': 0.12.10 axios: 0.27.2 cross-env: 7.0.3 dotenv: 16.0.1 - electron: 19.0.3 - electron-builder: 23.0.3 + electron: 19.0.8 + electron-builder: 23.3.1 electron-devtools-installer: 3.2.0 - electron-rebuild: 3.2.7 - electron-releases: 3.1026.0 - esbuild: 0.14.42 - eslint: 8.17.0 + electron-rebuild: 3.2.8 + electron-releases: 3.1072.0 + esbuild: 0.14.49 + eslint: 8.20.0 express-fileupload: 1.4.0 minimist: 1.2.6 - music-metadata: 7.12.3 + music-metadata: 7.12.4 open-cli: 7.0.1 - ora: 6.1.0 + ora: 6.1.2 picocolors: 1.0.0 - prettier: 2.6.2 - typescript: 4.7.3 + prettier: 2.7.1 + typescript: 4.7.4 + vitest: 0.12.10_@vitest+ui@0.12.10 wait-on: 6.0.1 packages/web: specifiers: '@emotion/css': ^11.9.0 - '@sentry/react': ^6.19.7 - '@sentry/tracing': ^6.19.7 + '@sentry/react': ^7.8.0 + '@sentry/tracing': ^7.8.0 '@storybook/addon-actions': ^6.5.5 '@storybook/addon-essentials': ^6.5.5 '@storybook/addon-interactions': ^6.5.5 @@ -117,6 +226,8 @@ importers: '@storybook/builder-vite': ^0.1.35 '@storybook/react': ^6.5.5 '@storybook/testing-library': ^0.0.11 + '@tanstack/react-query': ^4.0.10 + '@tanstack/react-query-devtools': ^4.0.10 '@testing-library/react': ^13.3.0 '@types/howler': ^2.2.7 '@types/js-cookie': ^3.0.2 @@ -148,7 +259,6 @@ importers: lodash-es: ^4.17.21 md5: ^2.3.0 open-cli: ^7.0.1 - plyr: ^3.7.2 plyr-react: ^5.0.2 postcss: ^8.4.14 prettier: '*' @@ -159,10 +269,9 @@ importers: react-error-boundary: ^3.1.4 react-ga4: ^1.4.1 react-hot-toast: ^2.2.0 - react-query: ^3.38.0 react-router-dom: ^6.3.0 react-use: ^17.4.0 - react-virtuoso: ^2.16.1 + react-virtuoso: ^2.16.5 rollup-plugin-visualizer: ^5.6.0 storybook-tailwind-dark-mode: ^1.0.12 tailwindcss: ^3.0.24 @@ -174,8 +283,10 @@ importers: vitest: ^0.12.10 dependencies: '@emotion/css': 11.9.0 - '@sentry/react': 6.19.7_react@18.1.0 - '@sentry/tracing': 6.19.7 + '@sentry/react': 7.8.0_react@18.1.0 + '@sentry/tracing': 7.8.0 + '@tanstack/react-query': 4.0.10_ef5jwxihqo6n7gxfmzogljlgcm + '@tanstack/react-query-devtools': 4.0.10_react@18.1.0 ahooks: 3.4.1_react@18.1.0 axios: 0.27.2 color.js: 1.2.0 @@ -187,7 +298,6 @@ importers: js-cookie: 3.0.1 lodash-es: 4.17.21 md5: 2.3.0 - plyr: 3.7.2 plyr-react: 5.0.2_react@18.1.0 qrcode: 1.5.0 react: 18.1.0 @@ -195,10 +305,9 @@ importers: react-error-boundary: 3.1.4_react@18.1.0 react-ga4: 1.4.1 react-hot-toast: 2.2.0_ef5jwxihqo6n7gxfmzogljlgcm - react-query: 3.39.1_ef5jwxihqo6n7gxfmzogljlgcm react-router-dom: 6.3.0_ef5jwxihqo6n7gxfmzogljlgcm react-use: 17.4.0_ef5jwxihqo6n7gxfmzogljlgcm - react-virtuoso: 2.16.1_ef5jwxihqo6n7gxfmzogljlgcm + react-virtuoso: 2.16.5_ef5jwxihqo6n7gxfmzogljlgcm valtio: 1.6.1_react@18.1.0+vite@2.9.9 devDependencies: '@storybook/addon-actions': 6.5.5_ef5jwxihqo6n7gxfmzogljlgcm @@ -308,29 +417,6 @@ packages: - supports-color dev: true - /@babel/core/7.17.10: - resolution: {integrity: sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.16.7 - '@babel/generator': 7.17.10 - '@babel/helper-compilation-targets': 7.17.10_@babel+core@7.17.10 - '@babel/helper-module-transforms': 7.17.7 - '@babel/helpers': 7.17.9 - '@babel/parser': 7.17.10 - '@babel/template': 7.16.7 - '@babel/traverse': 7.17.10 - '@babel/types': 7.17.10 - convert-source-map: 1.8.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.1 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/core/7.18.0: resolution: {integrity: sha512-Xyw74OlJwDijToNi0+6BBI5mLLR5+5R3bcSH80LXzjzEGEUlvNzujEE71BaD/ApEZHAvFI/Mlmp4M5lIkdeeWw==} engines: {node: '>=6.9.0'} @@ -377,15 +463,6 @@ packages: - supports-color dev: true - /@babel/generator/7.17.10: - resolution: {integrity: sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.17.10 - '@jridgewell/gen-mapping': 0.1.1 - jsesc: 2.5.2 - dev: true - /@babel/generator/7.18.0: resolution: {integrity: sha512-81YO9gGx6voPXlvYdZBliFXAZU8vZ9AZ6z+CjlmcnaeOcYSFbMTpdeDUO9xD9dh/68Vq03I8ZspfUTPfitcDHg==} engines: {node: '>=6.9.0'} @@ -408,7 +485,7 @@ packages: resolution: {integrity: sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.17.10 + '@babel/types': 7.18.2 dev: true /@babel/helper-builder-binary-assignment-operator-visitor/7.16.7: @@ -431,19 +508,6 @@ packages: semver: 6.3.0 dev: true - /@babel/helper-compilation-targets/7.17.10_@babel+core@7.17.10: - resolution: {integrity: sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.17.10 - '@babel/core': 7.17.10 - '@babel/helper-validator-option': 7.16.7 - browserslist: 4.20.3 - semver: 6.3.0 - dev: true - /@babel/helper-compilation-targets/7.17.10_@babel+core@7.18.0: resolution: {integrity: sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==} engines: {node: '>=6.9.0'} @@ -680,7 +744,7 @@ packages: resolution: {integrity: sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.0 + '@babel/types': 7.18.2 dev: true /@babel/helper-function-name/7.17.9: @@ -688,57 +752,41 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.16.7 - '@babel/types': 7.17.10 + '@babel/types': 7.18.2 dev: true /@babel/helper-hoist-variables/7.16.7: resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.17.10 + '@babel/types': 7.18.2 dev: true /@babel/helper-member-expression-to-functions/7.17.7: resolution: {integrity: sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.0 + '@babel/types': 7.18.2 dev: true /@babel/helper-module-imports/7.16.7: resolution: {integrity: sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.17.10 - - /@babel/helper-module-transforms/7.17.7: - resolution: {integrity: sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.16.7 - '@babel/helper-module-imports': 7.16.7 - '@babel/helper-simple-access': 7.17.7 - '@babel/helper-split-export-declaration': 7.16.7 - '@babel/helper-validator-identifier': 7.16.7 - '@babel/template': 7.16.7 - '@babel/traverse': 7.17.10 - '@babel/types': 7.17.10 - transitivePeerDependencies: - - supports-color - dev: true + '@babel/types': 7.18.2 /@babel/helper-module-transforms/7.18.0: resolution: {integrity: sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-environment-visitor': 7.16.7 + '@babel/helper-environment-visitor': 7.18.2 '@babel/helper-module-imports': 7.16.7 - '@babel/helper-simple-access': 7.17.7 + '@babel/helper-simple-access': 7.18.2 '@babel/helper-split-export-declaration': 7.16.7 '@babel/helper-validator-identifier': 7.16.7 '@babel/template': 7.16.7 - '@babel/traverse': 7.18.0 - '@babel/types': 7.18.0 + '@babel/traverse': 7.18.2 + '@babel/types': 7.18.2 transitivePeerDependencies: - supports-color dev: true @@ -747,18 +795,13 @@ packages: resolution: {integrity: sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.0 + '@babel/types': 7.18.2 dev: true /@babel/helper-plugin-utils/7.10.4: resolution: {integrity: sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==} dev: true - /@babel/helper-plugin-utils/7.16.7: - resolution: {integrity: sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==} - engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-plugin-utils/7.17.12: resolution: {integrity: sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==} engines: {node: '>=6.9.0'} @@ -825,7 +868,7 @@ packages: resolution: {integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.17.10 + '@babel/types': 7.18.2 dev: true /@babel/helper-validator-identifier/7.16.7: @@ -844,18 +887,7 @@ packages: '@babel/helper-function-name': 7.17.9 '@babel/template': 7.16.7 '@babel/traverse': 7.18.0 - '@babel/types': 7.18.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helpers/7.17.9: - resolution: {integrity: sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.16.7 - '@babel/traverse': 7.17.10 - '@babel/types': 7.17.10 + '@babel/types': 7.18.2 transitivePeerDependencies: - supports-color dev: true @@ -890,14 +922,6 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser/7.17.10: - resolution: {integrity: sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.17.10 - dev: true - /@babel/parser/7.18.0: resolution: {integrity: sha512-AqDccGC+m5O/iUStSJy3DGRIUFu7WbY/CppZYwrEUB4N0tZlnI8CSTsgL7v5fHVFmUbRv2sd+yy27o8Ydt4MGg==} engines: {node: '>=6.0.0'} @@ -1777,35 +1801,6 @@ packages: '@babel/helper-plugin-utils': 7.17.12 dev: true - /@babel/plugin-syntax-jsx/7.16.7: - resolution: {integrity: sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/helper-plugin-utils': 7.16.7 - dev: true - - /@babel/plugin-syntax-jsx/7.16.7_@babel+core@7.17.10: - resolution: {integrity: sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.17.10 - '@babel/helper-plugin-utils': 7.16.7 - dev: true - - /@babel/plugin-syntax-jsx/7.16.7_@babel+core@7.18.2: - resolution: {integrity: sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.18.2 - '@babel/helper-plugin-utils': 7.16.7 - dev: true - /@babel/plugin-syntax-jsx/7.17.12: resolution: {integrity: sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog==} engines: {node: '>=6.9.0'} @@ -2911,17 +2906,7 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/plugin-transform-react-jsx': 7.17.3 - dev: true - - /@babel/plugin-transform-react-jsx-development/7.16.7_@babel+core@7.17.10: - resolution: {integrity: sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.17.10 - '@babel/plugin-transform-react-jsx': 7.17.3_@babel+core@7.17.10 + '@babel/plugin-transform-react-jsx': 7.17.12 dev: true /@babel/plugin-transform-react-jsx-development/7.16.7_@babel+core@7.18.2: @@ -2931,27 +2916,27 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.18.2 - '@babel/plugin-transform-react-jsx': 7.17.3_@babel+core@7.18.2 + '@babel/plugin-transform-react-jsx': 7.17.12_@babel+core@7.18.2 dev: true - /@babel/plugin-transform-react-jsx-self/7.16.7_@babel+core@7.17.10: + /@babel/plugin-transform-react-jsx-self/7.16.7_@babel+core@7.18.2: resolution: {integrity: sha512-oe5VuWs7J9ilH3BCCApGoYjHoSO48vkjX2CbA5bFVhIuO2HKxA3vyF7rleA4o6/4rTDbk6r8hBW7Ul8E+UZrpA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.10 - '@babel/helper-plugin-utils': 7.16.7 + '@babel/core': 7.18.2 + '@babel/helper-plugin-utils': 7.17.12 dev: true - /@babel/plugin-transform-react-jsx-source/7.16.7_@babel+core@7.17.10: + /@babel/plugin-transform-react-jsx-source/7.16.7_@babel+core@7.18.2: resolution: {integrity: sha512-rONFiQz9vgbsnaMtQlZCjIRwhJvlrPET8TabIUK2hzlXw9B9s2Ieaxte1SCOOXMbWRHodbKixNf3BLcWVOQ8Bw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.10 - '@babel/helper-plugin-utils': 7.16.7 + '@babel/core': 7.18.2 + '@babel/helper-plugin-utils': 7.17.12 dev: true /@babel/plugin-transform-react-jsx/7.17.12: @@ -2964,7 +2949,7 @@ packages: '@babel/helper-module-imports': 7.16.7 '@babel/helper-plugin-utils': 7.17.12 '@babel/plugin-syntax-jsx': 7.17.12 - '@babel/types': 7.18.0 + '@babel/types': 7.18.2 dev: true /@babel/plugin-transform-react-jsx/7.17.12_@babel+core@7.18.0: @@ -2992,48 +2977,7 @@ packages: '@babel/helper-module-imports': 7.16.7 '@babel/helper-plugin-utils': 7.17.12 '@babel/plugin-syntax-jsx': 7.17.12_@babel+core@7.18.2 - '@babel/types': 7.18.0 - dev: true - - /@babel/plugin-transform-react-jsx/7.17.3: - resolution: {integrity: sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/helper-annotate-as-pure': 7.16.7 - '@babel/helper-module-imports': 7.16.7 - '@babel/helper-plugin-utils': 7.16.7 - '@babel/plugin-syntax-jsx': 7.16.7 - '@babel/types': 7.17.10 - dev: true - - /@babel/plugin-transform-react-jsx/7.17.3_@babel+core@7.17.10: - resolution: {integrity: sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.17.10 - '@babel/helper-annotate-as-pure': 7.16.7 - '@babel/helper-module-imports': 7.16.7 - '@babel/helper-plugin-utils': 7.16.7 - '@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.17.10 - '@babel/types': 7.17.10 - dev: true - - /@babel/plugin-transform-react-jsx/7.17.3_@babel+core@7.18.2: - resolution: {integrity: sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.18.2 - '@babel/helper-annotate-as-pure': 7.16.7 - '@babel/helper-module-imports': 7.16.7 - '@babel/helper-plugin-utils': 7.16.7 - '@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.18.2 - '@babel/types': 7.17.10 + '@babel/types': 7.18.2 dev: true /@babel/plugin-transform-react-pure-annotations/7.18.0: @@ -3805,6 +3749,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.9 + dev: true /@babel/runtime/7.18.3: resolution: {integrity: sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==} @@ -3829,26 +3774,8 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.16.7 - '@babel/parser': 7.17.10 - '@babel/types': 7.17.10 - dev: true - - /@babel/traverse/7.17.10: - resolution: {integrity: sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.16.7 - '@babel/generator': 7.17.10 - '@babel/helper-environment-visitor': 7.16.7 - '@babel/helper-function-name': 7.17.9 - '@babel/helper-hoist-variables': 7.16.7 - '@babel/helper-split-export-declaration': 7.16.7 - '@babel/parser': 7.17.10 - '@babel/types': 7.17.10 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + '@babel/parser': 7.18.3 + '@babel/types': 7.18.2 dev: true /@babel/traverse/7.18.0: @@ -3893,6 +3820,7 @@ packages: dependencies: '@babel/helper-validator-identifier': 7.16.7 to-fast-properties: 2.0.0 + dev: true /@babel/types/7.18.0: resolution: {integrity: sha512-vhAmLPAiC8j9K2GnsnLPCIH5wCrPpYIVBCWRBFDCB7Y/BXLqi/O+1RSTTM2bsmg6U/551+FCf9PNPxjABmxHTw==} @@ -3908,7 +3836,6 @@ packages: dependencies: '@babel/helper-validator-identifier': 7.16.7 to-fast-properties: 2.0.0 - dev: true /@base2/pretty-print-object/1.0.1: resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==} @@ -4031,21 +3958,6 @@ packages: - supports-color dev: true - /@electron/universal/1.2.0: - resolution: {integrity: sha512-eu20BwNsrMPKoe2bZ3/l9c78LclDvxg3PlVXrQf3L50NaUuW5M59gbPytI+V4z7/QMrohUHetQaU0ou+p1UG9Q==} - engines: {node: '>=8.6'} - dependencies: - '@malept/cross-spawn-promise': 1.1.1 - asar: 3.1.0 - debug: 4.3.4 - dir-compare: 2.4.0 - fs-extra: 9.1.0 - minimatch: 3.1.2 - plist: 3.0.5 - transitivePeerDependencies: - - supports-color - dev: true - /@electron/universal/1.2.1: resolution: {integrity: sha512-7323HyMh7KBAl/nPDppdLsC87G6RwRU02dy5FPeGB1eS7rUePh55+WNWiDPLhFQqqVPHzh77M69uhmoT8XnwMQ==} engines: {node: '>=8.6'} @@ -4056,7 +3968,7 @@ packages: dir-compare: 2.4.0 fs-extra: 9.1.0 minimatch: 3.1.2 - plist: 3.0.5 + plist: 3.0.6 transitivePeerDependencies: - supports-color dev: true @@ -4383,6 +4295,10 @@ packages: '@jridgewell/sourcemap-codec': 1.4.13 dev: true + /@leichtgewicht/ip-codec/2.0.4: + resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==} + dev: false + /@malept/cross-spawn-promise/1.1.1: resolution: {integrity: sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==} engines: {node: '>= 10'} @@ -4461,7 +4377,6 @@ packages: dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: true /@nodelib/fs.stat/1.1.3: resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==} @@ -4471,7 +4386,6 @@ packages: /@nodelib/fs.stat/2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true /@nodelib/fs.walk/1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} @@ -4479,7 +4393,6 @@ packages: dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.13.0 - dev: true /@npmcli/fs/1.1.1: resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} @@ -4488,6 +4401,14 @@ packages: semver: 7.3.7 dev: true + /@npmcli/fs/2.1.0: + resolution: {integrity: sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.3.7 + dev: true + /@npmcli/move-file/1.1.2: resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} engines: {node: '>=10'} @@ -4496,6 +4417,14 @@ packages: rimraf: 3.0.2 dev: true + /@npmcli/move-file/2.0.0: + resolution: {integrity: sha512-UR6D5f4KEGWJV6BGPH3Qb2EtgH+t+1XQ1Tt85c7qicN6cezzuHPdZwwAxqZr4JLtnQu0LZsTza/5gmNmSl8XLg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + dev: true + /@pmmmwh/react-refresh-webpack-plugin/0.5.7_jj4bc5mcn3kl4p4jwsxgmjil3i: resolution: {integrity: sha512-bcKCAzF0DV2IIROp9ZHkRJa6O4jy7NlnHdWL3GmcUxYWNjLXkK5kfELELwEfSP5hXPfVL/qOGMAROuMQb9GG8Q==} engines: {node: '>= 10.13'} @@ -4539,6 +4468,49 @@ packages: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true + /@protobufjs/aspromise/1.1.2: + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + dev: false + + /@protobufjs/base64/1.1.2: + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + dev: false + + /@protobufjs/codegen/2.0.4: + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + dev: false + + /@protobufjs/eventemitter/1.1.0: + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + dev: false + + /@protobufjs/fetch/1.1.0: + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + dev: false + + /@protobufjs/float/1.0.2: + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + dev: false + + /@protobufjs/inquire/1.1.0: + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + dev: false + + /@protobufjs/path/1.1.2: + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + dev: false + + /@protobufjs/pool/1.1.0: + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + dev: false + + /@protobufjs/utf8/1.1.0: + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + dev: false + /@rollup/plugin-babel/5.3.1_4kojsos35jimftt7mhjohcqk6y: resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} @@ -4601,13 +4573,34 @@ packages: picomatch: 2.3.1 dev: true - /@sentry/browser/6.19.7: - resolution: {integrity: sha512-oDbklp4O3MtAM4mtuwyZLrgO1qDVYIujzNJQzXmi9YzymJCuzMLSRDvhY83NNDCRxf0pds4DShgYeZdbSyKraA==} + /@sentry/browser/6.19.2: + resolution: {integrity: sha512-5VC44p5Vu2eJhVT39nLAJFgha5MjHDYCyZRR1ieeZt3a++otojPGBBAKNAtrEMGV+A2Z9AoneD6ZnDVlyb3GKg==} engines: {node: '>=6'} dependencies: - '@sentry/core': 6.19.7 - '@sentry/types': 6.19.7 - '@sentry/utils': 6.19.7 + '@sentry/core': 6.19.2 + '@sentry/types': 6.19.2 + '@sentry/utils': 6.19.2 + tslib: 1.14.1 + dev: false + + /@sentry/browser/7.8.0: + resolution: {integrity: sha512-khVrQ0/cfPgm4dAYc07TbHO+dGvaq5adjbIkzpQy0t64KI1GLz++JXv1GRHh5EF9J5kOTaDZX6EyKCa/zDNfxw==} + engines: {node: '>=8'} + dependencies: + '@sentry/core': 7.8.0 + '@sentry/types': 7.8.0 + '@sentry/utils': 7.8.0 + tslib: 1.14.1 + dev: false + + /@sentry/core/6.19.2: + resolution: {integrity: sha512-yu1R3ewBT4udmB4v7sc4biQZ0Z0rfB9+TzB5ZKoCftbe6kqXjFMMaFRYNUF9HicVldKAsBktgkWw3+yfqGkw/A==} + engines: {node: '>=6'} + dependencies: + '@sentry/hub': 6.19.2 + '@sentry/minimal': 6.19.2 + '@sentry/types': 6.19.2 + '@sentry/utils': 6.19.2 tslib: 1.14.1 dev: false @@ -4622,6 +4615,39 @@ packages: tslib: 1.14.1 dev: false + /@sentry/core/7.8.0: + resolution: {integrity: sha512-Xogwy96P6o3qgSLIGHxzKnRxrky8QdHpnS4A6ZWjnnFFAJmMg3MPF9SmqK5dOUpO9K69jTad9vs6ES2qTydfIw==} + engines: {node: '>=8'} + dependencies: + '@sentry/hub': 7.8.0 + '@sentry/types': 7.8.0 + '@sentry/utils': 7.8.0 + tslib: 1.14.1 + dev: false + + /@sentry/electron/3.0.7: + resolution: {integrity: sha512-Rahi1jgvjHnx1jGkkPPvDCxSCAME7xc2eBcFCLb4R/WDuNblR7tgJUuAtzv9JpxUgRHy1oLNct0wcvIu1mcXoA==} + dependencies: + '@sentry/browser': 6.19.2 + '@sentry/core': 6.19.2 + '@sentry/node': 6.19.2 + '@sentry/types': 6.19.2 + '@sentry/utils': 6.19.2 + deepmerge: 4.2.2 + tslib: 2.4.0 + transitivePeerDependencies: + - supports-color + dev: false + + /@sentry/hub/6.19.2: + resolution: {integrity: sha512-W7KCgNBgdBIMagOxy5J5KQPe+maYxSqfE8a5ncQ3R8BcZDQEKnkW/1FplNbfRLZqA/tL/ndKb7pTPqVtzsbARw==} + engines: {node: '>=6'} + dependencies: + '@sentry/types': 6.19.2 + '@sentry/utils': 6.19.2 + tslib: 1.14.1 + dev: false + /@sentry/hub/6.19.7: resolution: {integrity: sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==} engines: {node: '>=6'} @@ -4631,6 +4657,24 @@ packages: tslib: 1.14.1 dev: false + /@sentry/hub/7.8.0: + resolution: {integrity: sha512-L+aZ7XQJ5cM9NFBy/4caTyBVOc5DB6LK1wxPSFxCy1zsr/XpEYqTAy6ATRUeC0UKxdd/sN/lnQ8liGwVAc0gGQ==} + engines: {node: '>=8'} + dependencies: + '@sentry/types': 7.8.0 + '@sentry/utils': 7.8.0 + tslib: 1.14.1 + dev: false + + /@sentry/minimal/6.19.2: + resolution: {integrity: sha512-ClwxKm77iDHET7kpzv1JvzDx1er5DoNu+EUjst0kQzARIrXvu9xuZuE2/CnBWycQWqw8o3HoGoKz65uIhsUCzQ==} + engines: {node: '>=6'} + dependencies: + '@sentry/hub': 6.19.2 + '@sentry/types': 6.19.2 + tslib: 1.14.1 + dev: false + /@sentry/minimal/6.19.7: resolution: {integrity: sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ==} engines: {node: '>=6'} @@ -4640,6 +4684,22 @@ packages: tslib: 1.14.1 dev: false + /@sentry/node/6.19.2: + resolution: {integrity: sha512-Z1qREpTpYHxaeWjc1zMUk8ZTAp1WbxMiI2TVNc+a14DVT19Z2xNXb06MiRfeLgNc9lVGdmzR62dPmMBjVgPJYg==} + engines: {node: '>=6'} + dependencies: + '@sentry/core': 6.19.2 + '@sentry/hub': 6.19.2 + '@sentry/types': 6.19.2 + '@sentry/utils': 6.19.2 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + dev: false + /@sentry/node/6.19.7: resolution: {integrity: sha512-gtmRC4dAXKODMpHXKfrkfvyBL3cI8y64vEi3fDD046uqYcrWdgoQsffuBbxMAizc6Ez1ia+f0Flue6p15Qaltg==} engines: {node: '>=6'} @@ -4656,16 +4716,15 @@ packages: - supports-color dev: false - /@sentry/react/6.19.7_react@18.1.0: - resolution: {integrity: sha512-VzJeBg/v41jfxUYPkH2WYrKjWc4YiMLzDX0f4Zf6WkJ4v3IlDDSkX6DfmWekjTKBho6wiMkSNy2hJ1dHfGZ9jA==} - engines: {node: '>=6'} + /@sentry/react/7.8.0_react@18.1.0: + resolution: {integrity: sha512-oQLyRAyCBbb1sGnRjpeRNt7fKYYPoCM0XYiDdmudLFoQLkBNaVRm/JmYa+Ja009zV8NPG5v9yC8Ys/mIBLRgvg==} + engines: {node: '>=8'} peerDependencies: react: 15.x || 16.x || 17.x || 18.x dependencies: - '@sentry/browser': 6.19.7 - '@sentry/minimal': 6.19.7 - '@sentry/types': 6.19.7 - '@sentry/utils': 6.19.7 + '@sentry/browser': 7.8.0 + '@sentry/types': 7.8.0 + '@sentry/utils': 7.8.0 hoist-non-react-statics: 3.3.2 react: 18.1.0 tslib: 1.14.1 @@ -4682,11 +4741,39 @@ packages: tslib: 1.14.1 dev: false + /@sentry/tracing/7.8.0: + resolution: {integrity: sha512-qhem3wJgyd2tgRk0nHMGkWtiI3ln0ZdN8N+5hLnW+CrSz8Xm5/L5gwWQszOFG7WCYM3wRYEV093MuHg+qTg8iA==} + engines: {node: '>=8'} + dependencies: + '@sentry/hub': 7.8.0 + '@sentry/types': 7.8.0 + '@sentry/utils': 7.8.0 + tslib: 1.14.1 + dev: false + + /@sentry/types/6.19.2: + resolution: {integrity: sha512-XO5qmVBdTs+7PdCz7fAwn1afWxSnRE2KLBFg5/vOdKosPSSHsSHUURSkxiEZc2QsR+JpRB4AeQ26AkIRX38qTg==} + engines: {node: '>=6'} + dev: false + /@sentry/types/6.19.7: resolution: {integrity: sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==} engines: {node: '>=6'} dev: false + /@sentry/types/7.8.0: + resolution: {integrity: sha512-X9D2jlcAzbJdCHA+eCMv2t5HI9769Qpx48e+sZiK7Oasy1jwQtqzQRaiI9fy/zZ+p7Fyerj/4WjW/E2c4dJ63w==} + engines: {node: '>=8'} + dev: false + + /@sentry/utils/6.19.2: + resolution: {integrity: sha512-2DQQ2OJaxjtyxGq5FmMlqb6hptsqMs2xoBiVRMkTS/rvyTrk1oQdKZ8ePwjtgX3nJ728ni3IXIyXV+vfGp4EBw==} + engines: {node: '>=6'} + dependencies: + '@sentry/types': 6.19.2 + tslib: 1.14.1 + dev: false + /@sentry/utils/6.19.7: resolution: {integrity: sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==} engines: {node: '>=6'} @@ -4695,6 +4782,14 @@ packages: tslib: 1.14.1 dev: false + /@sentry/utils/7.8.0: + resolution: {integrity: sha512-6WvXawUPs60R9MitHXFL533D/Ic9tqQZbvPnBXmAkfp90Y5rcoq2QfJjkqMk/Z+Gnplwi8/wcJCC8EtYKfWg6w==} + engines: {node: '>=8'} + dependencies: + '@sentry/types': 7.8.0 + tslib: 1.14.1 + dev: false + /@sideway/address/4.1.4: resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==} dependencies: @@ -5778,7 +5873,7 @@ packages: '@babel/traverse': 7.18.0 '@babel/types': 7.18.0 '@storybook/csf': 0.0.2--canary.4566f4d.1 - '@storybook/mdx1-csf': 0.0.2-canary.5.6cee405.0_obpnotbfpw3vqhxpouazlalzou + '@storybook/mdx1-csf': 0.0.5-canary.13.9ce928a.0_obpnotbfpw3vqhxpouazlalzou core-js: 3.22.5 fs-extra: 9.1.0 global: 4.4.0 @@ -5964,8 +6059,8 @@ packages: - supports-color dev: true - /@storybook/mdx1-csf/0.0.2-canary.5.6cee405.0_obpnotbfpw3vqhxpouazlalzou: - resolution: {integrity: sha512-LRQ086H27/Ro8jQPoXb3hb0LgYokurqqFf4eDNSv/EqvzUihGrurvpiIGfTJ6JDzWZbiX1NIsqe8dx4jKpEGMw==} + /@storybook/mdx1-csf/0.0.5-canary.13.9ce928a.0_obpnotbfpw3vqhxpouazlalzou: + resolution: {integrity: sha512-K4wqrObf2Yu3djRMR5hnorTBA9VIl19qpGbna3TsJNA7WzADHKdEMXrURkZOkEN5YPTui4irfw06mo/D3+eeIg==} dependencies: '@babel/generator': 7.18.2 '@babel/parser': 7.18.3 @@ -6398,6 +6493,46 @@ packages: defer-to-connect: 2.0.1 dev: true + /@tanstack/match-sorter-utils/8.1.1: + resolution: {integrity: sha512-IdmEekEYxQsoLOR0XQyw3jD1GujBpRRYaGJYQUw1eOT1eUugWxdc7jomh1VQ1EKHcdwDLpLaCz/8y4KraU4T9A==} + engines: {node: '>=12'} + dependencies: + remove-accents: 0.4.2 + dev: false + + /@tanstack/query-core/4.0.10: + resolution: {integrity: sha512-9LsABpZXkWZHi4P1ozRETEDXQocLAxVzQaIhganxbNuz/uA3PsCAJxJTiQrknG5htLMzOF5MqM9G10e6DCxV1A==} + dev: false + + /@tanstack/react-query-devtools/4.0.10_react@18.1.0: + resolution: {integrity: sha512-3J7LLYQjfjTI0DbPo0bA+M3l4kdvYSWAqihpeG1u93WVyZj0OEFviUv+4cK7+k2AVgQJAPMZ5xvtewKxOOFVrw==} + dependencies: + '@tanstack/match-sorter-utils': 8.1.1 + '@types/use-sync-external-store': 0.0.3 + use-sync-external-store: 1.2.0_react@18.1.0 + transitivePeerDependencies: + - react + dev: false + + /@tanstack/react-query/4.0.10_ef5jwxihqo6n7gxfmzogljlgcm: + resolution: {integrity: sha512-Wn5QhZUE5wvr6rGClV7KeQIUsdTmYR9mgmMZen7DSRWauHW2UTynFg3Kkf6pw+XlxxOLsyLWwz/Q6q1lSpM3TQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@tanstack/query-core': 4.0.10 + '@types/use-sync-external-store': 0.0.3 + react: 18.1.0 + react-dom: 18.1.0_react@18.1.0 + use-sync-external-store: 1.2.0_react@18.1.0 + dev: false + /@testing-library/dom/8.13.0: resolution: {integrity: sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==} engines: {node: '>=12'} @@ -6442,6 +6577,7 @@ packages: /@tootallnate/once/1.1.2: resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} + dev: false /@tootallnate/once/2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} @@ -6460,20 +6596,20 @@ packages: /@types/better-sqlite3/7.5.0: resolution: {integrity: sha512-G9ZbMjydW2yj1AgiPlUtdgF3a1qNpLJLudc9ynJCeJByS3XFWpmT9LT+VSHrKHFbxb31CvtYwetLTOvG9zdxdg==} dependencies: - '@types/node': 17.0.32 + '@types/node': 18.0.6 dev: true /@types/body-parser/1.19.2: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 17.0.32 + '@types/node': 18.0.6 dev: true /@types/busboy/0.3.2: resolution: {integrity: sha512-iEvdm9Z9KdSs/ozuh1Z7ZsXrOl8F4M/CLMXPZHr3QuJ4d6Bjn+HBMC5EMKpwpAo8oi8iK9GZfFoHaIMrrZgwVw==} dependencies: - '@types/node': 17.0.32 + '@types/node': 18.0.6 dev: true /@types/cacheable-request/6.0.2: @@ -6481,7 +6617,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 17.0.32 + '@types/node': 18.0.6 '@types/responselike': 1.0.0 dev: true @@ -6498,7 +6634,7 @@ packages: /@types/connect/3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 17.0.32 + '@types/node': 18.0.6 dev: true /@types/cookie-parser/1.4.3: @@ -6545,7 +6681,7 @@ packages: /@types/express-serve-static-core/4.17.28: resolution: {integrity: sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==} dependencies: - '@types/node': 17.0.32 + '@types/node': 18.0.6 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 dev: true @@ -6562,15 +6698,14 @@ packages: /@types/fs-extra/9.0.13: resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} dependencies: - '@types/node': 17.0.32 - dev: true + '@types/node': 18.0.6 /@types/glob/7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} requiresBuild: true dependencies: '@types/minimatch': 3.0.5 - '@types/node': 17.0.32 + '@types/node': 18.0.6 dev: true /@types/graceful-fs/4.1.5: @@ -6636,7 +6771,7 @@ packages: /@types/keyv/3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 17.0.32 + '@types/node': 18.0.6 dev: true /@types/lodash-es/4.17.6: @@ -6649,6 +6784,10 @@ packages: resolution: {integrity: sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==} dev: true + /@types/long/4.0.2: + resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} + dev: false + /@types/md5/2.3.2: resolution: {integrity: sha512-v+JFDu96+UYJ3/UWzB0mEglIS//MZXgRaJ4ubUPwOM0gvLc/kcQ3TWNYwENEK7/EcXGQVrW8h/XqednSjBd/Og==} dev: true @@ -6669,7 +6808,6 @@ packages: /@types/minimist/1.2.2: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} - dev: true /@types/ms/0.7.31: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} @@ -6690,14 +6828,11 @@ packages: resolution: {integrity: sha512-eAIcfAvhf/BkHcf4pkLJ7ECpBAhh9kcxRBpip9cTiO+hf+aJrsxYxBeS6OXvOd9WqNAJmavXVpZvY1rBjNsXmw==} dev: true - /@types/node/17.0.35: - resolution: {integrity: sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==} - dev: true - optional: true - /@types/node/17.0.36: resolution: {integrity: sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==} - dev: true + + /@types/node/18.0.6: + resolution: {integrity: sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==} /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -6717,7 +6852,7 @@ packages: /@types/plist/3.0.2: resolution: {integrity: sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==} dependencies: - '@types/node': 17.0.35 + '@types/node': 18.0.6 xmlbuilder: 15.1.1 dev: true optional: true @@ -6730,6 +6865,10 @@ packages: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} dev: true + /@types/ps-tree/1.1.2: + resolution: {integrity: sha512-ZREFYlpUmPQJ0esjxoG1fMvB2HNaD3z+mjqdSosZvd3RalncI9NEur73P8ZJz4YQdL64CmV1w0RuqoRUlhQRBw==} + dev: false + /@types/qrcode/1.4.2: resolution: {integrity: sha512-7uNT9L4WQTNJejHTSTdaJhfBSCN73xtXaHFyBJ8TSwiLhe4PRuTue7Iph0s2nG9R/ifUaSnGhLUOZavlBEqDWQ==} dependencies: @@ -6773,7 +6912,7 @@ packages: /@types/responselike/1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 17.0.32 + '@types/node': 18.0.6 dev: true /@types/scheduler/0.16.2: @@ -6784,7 +6923,7 @@ packages: resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} dependencies: '@types/mime': 1.3.2 - '@types/node': 17.0.32 + '@types/node': 18.0.6 dev: true /@types/source-list-map/0.1.2: @@ -6815,6 +6954,10 @@ packages: resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} dev: true + /@types/use-sync-external-store/0.0.3: + resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} + dev: false + /@types/verror/1.10.5: resolution: {integrity: sha512-9UjMCHK5GPgQRoNbqdLIAvAy0EInuiqbW0PBMtVP6B5B2HQJlvoJHM+KodPZMEjOa5VkSc+5LH7xy+cUzQdmHw==} dev: true @@ -6847,6 +6990,10 @@ packages: source-map: 0.6.1 dev: true + /@types/which/2.0.1: + resolution: {integrity: sha512-Jjakcv8Roqtio6w1gr0D7y6twbhx6gGgFGF5BLwajPpnOIOxFkakFhCq+LmyyeAz7BX6ULrjBOxdKaCDy+4+dQ==} + dev: false + /@types/yargs-parser/21.0.0: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} dev: true @@ -6896,6 +7043,33 @@ packages: - supports-color dev: true + /@typescript-eslint/eslint-plugin/5.30.7_6wltbjakwuqm7awqswigmiuhd4: + resolution: {integrity: sha512-l4L6Do+tfeM2OK0GJsU7TUcM/1oN/N25xHm3Jb4z3OiDU4Lj8dIuxX9LpVMS9riSXQs42D1ieX7b85/r16H9Fw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/parser': 5.30.7_he2ccbldppg44uulnyq4rwocfa + '@typescript-eslint/scope-manager': 5.30.7 + '@typescript-eslint/type-utils': 5.30.7_he2ccbldppg44uulnyq4rwocfa + '@typescript-eslint/utils': 5.30.7_he2ccbldppg44uulnyq4rwocfa + debug: 4.3.4 + eslint: 8.20.0 + functional-red-black-tree: 1.0.1 + ignore: 5.2.0 + regexpp: 3.2.0 + semver: 7.3.7 + tsutils: 3.21.0_typescript@4.7.4 + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/parser/5.27.0_ud6rd4xtew5bv4yhvkvu24pzm4: resolution: {integrity: sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6916,6 +7090,26 @@ packages: - supports-color dev: true + /@typescript-eslint/parser/5.30.7_he2ccbldppg44uulnyq4rwocfa: + resolution: {integrity: sha512-Rg5xwznHWWSy7v2o0cdho6n+xLhK2gntImp0rJroVVFkcYFYQ8C8UJTSuTw/3CnExBmPjycjmUJkxVmjXsld6A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.30.7 + '@typescript-eslint/types': 5.30.7 + '@typescript-eslint/typescript-estree': 5.30.7_typescript@4.7.4 + debug: 4.3.4 + eslint: 8.20.0 + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/scope-manager/5.27.0: resolution: {integrity: sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6924,6 +7118,14 @@ packages: '@typescript-eslint/visitor-keys': 5.27.0 dev: true + /@typescript-eslint/scope-manager/5.30.7: + resolution: {integrity: sha512-7BM1bwvdF1UUvt+b9smhqdc/eniOnCKxQT/kj3oXtj3LqnTWCAM0qHRHfyzCzhEfWX0zrW7KqXXeE4DlchZBKw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.30.7 + '@typescript-eslint/visitor-keys': 5.30.7 + dev: true + /@typescript-eslint/type-utils/5.27.0_ud6rd4xtew5bv4yhvkvu24pzm4: resolution: {integrity: sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6943,11 +7145,35 @@ packages: - supports-color dev: true + /@typescript-eslint/type-utils/5.30.7_he2ccbldppg44uulnyq4rwocfa: + resolution: {integrity: sha512-nD5qAE2aJX/YLyKMvOU5jvJyku4QN5XBVsoTynFrjQZaDgDV6i7QHFiYCx10wvn7hFvfuqIRNBtsgaLe0DbWhw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/utils': 5.30.7_he2ccbldppg44uulnyq4rwocfa + debug: 4.3.4 + eslint: 8.20.0 + tsutils: 3.21.0_typescript@4.7.4 + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/types/5.27.0: resolution: {integrity: sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@typescript-eslint/types/5.30.7: + resolution: {integrity: sha512-ocVkETUs82+U+HowkovV6uxf1AnVRKCmDRNUBUUo46/5SQv1owC/EBFkiu4MOHeZqhKz2ktZ3kvJJ1uFqQ8QPg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /@typescript-eslint/typescript-estree/5.27.0_typescript@4.7.3: resolution: {integrity: sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6969,6 +7195,27 @@ packages: - supports-color dev: true + /@typescript-eslint/typescript-estree/5.30.7_typescript@4.7.4: + resolution: {integrity: sha512-tNslqXI1ZdmXXrHER83TJ8OTYl4epUzJC0aj2i4DMDT4iU+UqLT3EJeGQvJ17BMbm31x5scSwo3hPM0nqQ1AEA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.30.7 + '@typescript-eslint/visitor-keys': 5.30.7 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.7 + tsutils: 3.21.0_typescript@4.7.4 + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/utils/5.27.0_ud6rd4xtew5bv4yhvkvu24pzm4: resolution: {integrity: sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6987,6 +7234,24 @@ packages: - typescript dev: true + /@typescript-eslint/utils/5.30.7_he2ccbldppg44uulnyq4rwocfa: + resolution: {integrity: sha512-Z3pHdbFw+ftZiGUnm1GZhkJgVqsDL5CYW2yj+TB2mfXDFOMqtbzQi2dNJIyPqPbx9mv2kUxS1gU+r2gKlKi1rQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.11 + '@typescript-eslint/scope-manager': 5.30.7 + '@typescript-eslint/types': 5.30.7 + '@typescript-eslint/typescript-estree': 5.30.7_typescript@4.7.4 + eslint: 8.20.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.20.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + /@typescript-eslint/visitor-keys/5.27.0: resolution: {integrity: sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6995,6 +7260,14 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /@typescript-eslint/visitor-keys/5.30.7: + resolution: {integrity: sha512-KrRXf8nnjvcpxDFOKej4xkD7657+PClJs5cJVSG7NNoCNnjEdc46juNAQt7AyuWctuCgs6mVRc1xGctEqrjxWw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.30.7 + eslint-visitor-keys: 3.3.0 + dev: true + /@unblockneteasemusic/rust-napi-android-arm-eabi/0.3.0: resolution: {integrity: sha512-PSgb5j8sSs4gGUBy3FcPvQTsLlCc6HknyyK5Ax7caUMEzGK/oTFhpwkldulidc+eLh5mRCuNeKq9NvdMZuYp6A==} engines: {node: '>= 10'} @@ -7158,11 +7431,11 @@ packages: resolution: {integrity: sha512-aurBNmMo0kz1O4qRoY+FM4epSA39y3ShWGuqfLRA/3z0oEJAdtoSfgA3aO98/PCCHAqMaduLxIxErWrVKIFzXA==} engines: {node: '>=12.0.0'} dependencies: - '@babel/core': 7.17.10 - '@babel/plugin-transform-react-jsx': 7.17.3_@babel+core@7.17.10 - '@babel/plugin-transform-react-jsx-development': 7.16.7_@babel+core@7.17.10 - '@babel/plugin-transform-react-jsx-self': 7.16.7_@babel+core@7.17.10 - '@babel/plugin-transform-react-jsx-source': 7.16.7_@babel+core@7.17.10 + '@babel/core': 7.18.2 + '@babel/plugin-transform-react-jsx': 7.17.12_@babel+core@7.18.2 + '@babel/plugin-transform-react-jsx-development': 7.16.7_@babel+core@7.18.2 + '@babel/plugin-transform-react-jsx-self': 7.16.7_@babel+core@7.18.2 + '@babel/plugin-transform-react-jsx-source': 7.16.7_@babel+core@7.18.2 '@rollup/pluginutils': 4.2.1 react-refresh: 0.13.0 resolve: 1.22.0 @@ -7421,8 +7694,8 @@ packages: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} dev: true - /NeteaseCloudMusicApi/4.6.2: - resolution: {integrity: sha512-W4Okv0VCktso6w9CAFzOxinNvY+kJA6S6Z7i8oJd9N/FbDS+qTTytmlOClOHwdEdPlIRKR4MKKKE65HghmY7cg==} + /NeteaseCloudMusicApi/4.6.7: + resolution: {integrity: sha512-Qw+r3ti2O5vgrqeOxOvlu+DNsTdzfxJ+nC6C5rjbwU2d4VMZZynqm8Sb+692WGQvZAjH5aTbXLnGAR8hBFJdEQ==} engines: {node: '>=12'} hasBin: true dependencies: @@ -7430,7 +7703,7 @@ packages: express: 4.18.1 express-fileupload: 1.4.0 md5: 2.3.0 - music-metadata: 7.12.3 + music-metadata: 7.12.4 pac-proxy-agent: 5.0.0 qrcode: 1.5.0 safe-decode-uri-component: 1.2.1 @@ -7657,7 +7930,7 @@ packages: dev: true /ansi-regex/2.1.1: - resolution: {integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=} + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} /ansi-regex/5.0.1: @@ -7720,23 +7993,23 @@ packages: resolution: {integrity: sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==} dev: true - /app-builder-lib/23.0.3: - resolution: {integrity: sha512-1qrtXYHXJfXhzJnMtVGjIva3067F1qYQubl2oBjI61gCBoCHvhghdYJ57XxXTQQ0VxnUhg1/Iaez87uXp8mD8w==} + /app-builder-lib/23.3.1: + resolution: {integrity: sha512-mi4DG3m32cMJ5CtO9iYk41gBvGWLzJjQsaQgGOd4ZhmIuKyj8M/0rT1g0s/0qD4Tw8jsa//NXMXCC7vpGIfkTg==} engines: {node: '>=14.0.0'} dependencies: '@develar/schema-utils': 2.6.5 - '@electron/universal': 1.2.0 + '@electron/universal': 1.2.1 '@malept/flatpak-bundler': 0.4.0 7zip-bin: 5.1.1 async-exit-hook: 2.0.1 bluebird-lst: 1.0.9 - builder-util: 23.0.2 - builder-util-runtime: 9.0.0 + builder-util: 23.3.0 + builder-util-runtime: 9.0.3 chromium-pickle-js: 0.2.0 debug: 4.3.4 - ejs: 3.1.7 + ejs: 3.1.8 electron-osx-sign: 0.6.0 - electron-publish: 23.0.2 + electron-publish: 23.3.0 form-data: 4.0.0 fs-extra: 10.1.0 hosted-git-info: 4.1.0 @@ -7748,6 +8021,7 @@ packages: read-config-file: 6.2.0 sanitize-filename: 1.6.3 semver: 7.3.7 + tar: 6.1.11 temp-file: 3.4.0 transitivePeerDependencies: - supports-color @@ -7906,7 +8180,7 @@ packages: dev: true /arrify/1.0.1: - resolution: {integrity: sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=} + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} dev: true @@ -7922,7 +8196,7 @@ packages: dependencies: chromium-pickle-js: 0.2.0 commander: 5.1.0 - glob: 7.2.0 + glob: 7.2.3 minimatch: 3.1.2 optionalDependencies: '@types/glob': 7.2.0 @@ -7938,7 +8212,7 @@ packages: dev: true /assert-plus/1.0.0: - resolution: {integrity: sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=} + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} dev: true optional: true @@ -7989,12 +8263,18 @@ packages: engines: {node: '>=0.12.0'} dev: true - /async/3.2.3: - resolution: {integrity: sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==} + /async/2.6.4: + resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} + dependencies: + lodash: 4.17.21 + dev: false + + /async/3.2.4: + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} dev: true /asynckit/0.4.0: - resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} /at-least-node/1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} @@ -8352,7 +8632,7 @@ packages: dev: true /binary/0.3.0: - resolution: {integrity: sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=} + resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==} dependencies: buffers: 0.1.1 chainsaw: 0.1.0 @@ -8385,12 +8665,11 @@ packages: dev: true /bluebird/3.4.7: - resolution: {integrity: sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=} + resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} dev: false /bluebird/3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - dev: true /bn.js/4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} @@ -8484,20 +8763,6 @@ packages: engines: {node: '>=8'} dependencies: fill-range: 7.0.1 - dev: true - - /broadcast-channel/3.7.0: - resolution: {integrity: sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==} - dependencies: - '@babel/runtime': 7.18.3 - detect-node: 2.1.0 - js-sha3: 0.8.0 - microseconds: 0.2.0 - nano-time: 1.0.0 - oblivious-set: 1.0.0 - rimraf: 3.0.2 - unload: 2.2.0 - dev: false /brorand/1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} @@ -8567,7 +8832,7 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001339 + caniuse-lite: 1.0.30001344 electron-to-chromium: 1.4.137 escalade: 3.1.1 node-releases: 2.0.4 @@ -8596,12 +8861,12 @@ packages: dev: true /buffer-equal/1.0.0: - resolution: {integrity: sha1-WWFrSYME1Var1GaWayLu2j7KX74=} + resolution: {integrity: sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==} engines: {node: '>=0.4.0'} dev: true /buffer-fill/1.0.0: - resolution: {integrity: sha1-+PeLdniYiO858gXNY39o5wISKyw=} + resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==} dev: true /buffer-from/1.1.2: @@ -8613,6 +8878,10 @@ packages: engines: {node: '>=0.10'} dev: false + /buffer-indexof/1.1.1: + resolution: {integrity: sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==} + dev: false + /buffer-xor/1.0.3: resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} dev: true @@ -8639,12 +8908,12 @@ packages: dev: true /buffers/0.1.1: - resolution: {integrity: sha1-skV5w77U1tOWru5tmorn9Ugqt7s=} + resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} engines: {node: '>=0.2.0'} dev: false - /builder-util-runtime/9.0.0: - resolution: {integrity: sha512-SkpEtSmTkREDHRJnxKEv43aAYp8sYWY8fxYBhGLBLOBIRXeaIp6Kv3lBgSD7uR8jQtC7CA659sqJrpSV6zNvSA==} + /builder-util-runtime/9.0.3: + resolution: {integrity: sha512-SfG2wnyjpUbbdtpnqDpWwklujofC6GarGpvdWrEkg9p5AD/xJmTF2buTNaqs3qtsNBEVQDDjZz9xc2GGpVyMfA==} engines: {node: '>=12.0.0'} dependencies: debug: 4.3.4 @@ -8653,15 +8922,15 @@ packages: - supports-color dev: true - /builder-util/23.0.2: - resolution: {integrity: sha512-HaNHL3axNW/Ms8O1mDx3I07G+ZnZ/TKSWWvorOAPau128cdt9S+lNx5ocbx8deSaHHX4WFXSZVHh3mxlaKJNgg==} + /builder-util/23.3.0: + resolution: {integrity: sha512-m7RRd21N2yrnuGFd+ZqOY0ryeqWmBslDKmGDVz0wETqoEEqpiJsF3CGlsb6MRN2EQKDubvE5e+lBf8ATt06fnA==} dependencies: '@types/debug': 4.1.7 '@types/fs-extra': 9.0.13 7zip-bin: 5.1.1 app-builder-bin: 4.0.0 bluebird-lst: 1.0.9 - builder-util-runtime: 9.0.0 + builder-util-runtime: 9.0.3 chalk: 4.1.2 cross-spawn: 7.0.3 debug: 4.3.4 @@ -8766,6 +9035,32 @@ packages: - bluebird dev: true + /cacache/16.1.1: + resolution: {integrity: sha512-VDKN+LHyCQXaaYZ7rA/qtkURU+/yYhviUdvqEv2LT6QPZU8jpyzEkEVAcKlKLt5dJ5BRp11ym8lo3NKLluEPLg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + '@npmcli/fs': 2.1.0 + '@npmcli/move-file': 2.0.0 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 8.0.3 + infer-owner: 1.0.4 + lru-cache: 7.13.1 + minipass: 3.3.4 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 9.0.1 + tar: 6.1.11 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + dev: true + /cache-base/1.0.1: resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} engines: {node: '>=0.10.0'} @@ -8899,6 +9194,24 @@ packages: engines: {node: '>=4'} dev: true + /castv2-client/1.2.0: + resolution: {integrity: sha512-2diOsC0vSSxa3QEOgoGBy9fZRHzNXatHz464Kje2OpwQ7GM5vulyrD0gLFOQ1P4rgLAFsYiSGQl4gK402nEEuA==} + dependencies: + castv2: 0.1.10 + debug: 2.6.9 + transitivePeerDependencies: + - supports-color + dev: false + + /castv2/0.1.10: + resolution: {integrity: sha512-3QWevHrjT22KdF08Y2a217IYCDQDP7vEJaY4n0lPBeC5UBYbMFMadDfVTsaQwq7wqsEgYUHElPGm3EO1ey+TNw==} + dependencies: + debug: 4.3.4 + protobufjs: 6.11.3 + transitivePeerDependencies: + - supports-color + dev: false + /ccount/1.1.0: resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} dev: true @@ -8917,7 +9230,7 @@ packages: dev: true /chainsaw/0.1.0: - resolution: {integrity: sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=} + resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==} dependencies: traverse: 0.3.9 dev: false @@ -8952,7 +9265,6 @@ packages: /chalk/5.0.1: resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: true /change-case/4.1.2: resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} @@ -8989,11 +9301,11 @@ packages: dev: true /charenc/0.0.2: - resolution: {integrity: sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=} + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} dev: false /check-error/1.0.2: - resolution: {integrity: sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=} + resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} dev: true /chokidar/2.1.8: @@ -9046,8 +9358,24 @@ packages: engines: {node: '>=6.0'} dev: true + /chromecast-api/0.4.0: + resolution: {integrity: sha512-8bc5cxfts33cUrmsfrjhueCJT6m+heeRrzjygyrCJxyUufweiV5j6HJDtuSV5YZxj3VqIgIHS29wgPVX0jci2g==} + engines: {node: '>=10.0.0'} + dependencies: + castv2-client: 1.2.0 + debug: 4.3.4 + dns-txt: 2.0.2 + mime: 3.0.0 + multicast-dns: 7.2.5 + node-ssdp: 4.0.1 + xml2js: 0.4.23 + youtube-remote: 1.0.2 + transitivePeerDependencies: + - supports-color + dev: false + /chromium-pickle-js/0.2.0: - resolution: {integrity: sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=} + resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} dev: true /ci-info/2.0.0: @@ -9154,13 +9482,13 @@ packages: dev: true /clone-response/1.0.2: - resolution: {integrity: sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=} + resolution: {integrity: sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==} dependencies: mimic-response: 1.0.1 dev: true /clone/1.0.4: - resolution: {integrity: sha1-2jCcwmPfFZlMaIypAheco8fNfH4=} + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} dev: true @@ -9175,7 +9503,7 @@ packages: dev: true /code-point-at/1.1.0: - resolution: {integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=} + resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} engines: {node: '>=0.10.0'} dev: false @@ -9203,7 +9531,7 @@ packages: color-name: 1.1.4 /color-name/1.1.3: - resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} /color-name/1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} @@ -9222,7 +9550,7 @@ packages: dev: false /colors/1.0.3: - resolution: {integrity: sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=} + resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} engines: {node: '>=0.1.90'} dev: true @@ -9241,7 +9569,7 @@ packages: dev: true /commander/2.9.0: - resolution: {integrity: sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=} + resolution: {integrity: sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==} engines: {node: '>= 0.6.x'} dependencies: graceful-readlink: 1.0.1 @@ -9281,7 +9609,7 @@ packages: dev: true /compare-version/0.1.2: - resolution: {integrity: sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=} + resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} engines: {node: '>=0.10.0'} dev: true @@ -9324,7 +9652,7 @@ packages: dev: true /concat-map/0.0.1: - resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} /concat-stream/1.6.2: resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} @@ -9372,12 +9700,17 @@ packages: xdg-basedir: 4.0.0 dev: true + /connect-history-api-fallback/2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + dev: false + /console-browserify/1.2.0: resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} dev: true /console-control-strings/1.1.0: - resolution: {integrity: sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=} + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} /constant-case/3.0.4: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} @@ -9415,7 +9748,7 @@ packages: dev: false /cookie-signature/1.0.6: - resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=} + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} /cookie/0.4.1: resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==} @@ -9609,7 +9942,7 @@ packages: dev: true /crypt/0.0.2: - resolution: {integrity: sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=} + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} dev: false /crypto-browserify/3.12.0: @@ -9766,6 +10099,11 @@ packages: engines: {node: '>= 6'} dev: false + /data-uri-to-buffer/4.0.0: + resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==} + engines: {node: '>= 12'} + dev: false + /data-urls/3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} @@ -9805,7 +10143,6 @@ packages: optional: true dependencies: ms: 2.1.3 - dev: true /debug/4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -9819,7 +10156,7 @@ packages: ms: 2.1.2 /decamelize-keys/1.1.0: - resolution: {integrity: sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=} + resolution: {integrity: sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==} engines: {node: '>=0.10.0'} dependencies: decamelize: 1.2.0 @@ -9827,7 +10164,7 @@ packages: dev: true /decamelize/1.2.0: - resolution: {integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=} + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} /decamelize/5.0.1: @@ -9845,7 +10182,7 @@ packages: dev: true /decompress-response/3.3.0: - resolution: {integrity: sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=} + resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} engines: {node: '>=4'} dependencies: mimic-response: 1.0.1 @@ -9882,7 +10219,6 @@ packages: /deepmerge/4.2.2: resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} engines: {node: '>=0.10.0'} - dev: true /default-browser-id/1.0.4: resolution: {integrity: sha512-qPy925qewwul9Hifs+3sx1ZYn14obHxpkX+mPD369w4Rzg+YkJBgi3SOvwUq81nWSjqGUegIgEPwD8u+HUnxlw==} @@ -9897,7 +10233,7 @@ packages: optional: true /defaults/1.0.3: - resolution: {integrity: sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=} + resolution: {integrity: sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==} dependencies: clone: 1.0.4 dev: true @@ -9975,14 +10311,14 @@ packages: dev: true /delayed-stream/1.0.0: - resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} /delegates/1.0.0: - resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=} + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} /depd/1.1.2: - resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=} + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} engines: {node: '>= 0.6'} dev: true @@ -10007,19 +10343,14 @@ packages: repeat-string: 1.6.1 dev: true - /detect-libc/1.0.3: - resolution: {integrity: sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=} - engines: {node: '>=0.10'} - hasBin: true - dev: true - /detect-libc/2.0.1: resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} engines: {node: '>=8'} - dev: false /detect-node/2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + dev: true + optional: true /detect-package-manager/2.0.1: resolution: {integrity: sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==} @@ -10087,18 +10418,17 @@ packages: engines: {node: '>=8'} dependencies: path-type: 4.0.0 - dev: true /dlv/1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} dev: true - /dmg-builder/23.0.3: - resolution: {integrity: sha512-mBYrHHnSM5PC656TDE+xTGmXIuWHAGmmRfyM+dV0kP+AxtwPof4pAXNQ8COd0/exZQ4dqf72FiPS3B9G9aB5IA==} + /dmg-builder/23.3.1: + resolution: {integrity: sha512-YH9KtqBUqn4xzT8W/4I12CBOJXXleHeCQ1UyUvrhNu50ujY/U7XJ4ZZCaKvU2sJesDJqWgY9rqxaZaWVKAi9KQ==} dependencies: - app-builder-lib: 23.0.3 - builder-util: 23.0.2 - builder-util-runtime: 9.0.0 + app-builder-lib: 23.3.1 + builder-util: 23.3.0 + builder-util-runtime: 9.0.3 fs-extra: 10.1.0 iconv-lite: 0.6.3 js-yaml: 4.1.0 @@ -10112,7 +10442,6 @@ packages: resolution: {integrity: sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==} engines: {node: '>=8'} os: [darwin] - deprecated: 'Disk image license agreements are deprecated by Apple and will probably be removed in a future macOS release. Discussion at: https://github.com/argv-minus-one/dmg-license/issues/11' hasBin: true requiresBuild: true dependencies: @@ -10121,12 +10450,25 @@ packages: ajv: 6.12.6 crc: 3.8.0 iconv-corefoundation: 1.1.7 - plist: 3.0.5 + plist: 3.0.6 smart-buffer: 4.2.0 verror: 1.10.1 dev: true optional: true + /dns-packet/5.4.0: + resolution: {integrity: sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==} + engines: {node: '>=6'} + dependencies: + '@leichtgewicht/ip-codec': 2.0.4 + dev: false + + /dns-txt/2.0.2: + resolution: {integrity: sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==} + dependencies: + buffer-indexof: 1.1.1 + dev: false + /doctrine/2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -10256,14 +10598,18 @@ packages: engines: {node: '>=10'} dev: true + /duplexer/0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + dev: false + /duplexer2/0.1.4: - resolution: {integrity: sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=} + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} dependencies: readable-stream: 2.3.7 dev: false /duplexer3/0.1.4: - resolution: {integrity: sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=} + resolution: {integrity: sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==} dev: true /duplexify/3.7.1: @@ -10276,7 +10622,7 @@ packages: dev: true /ee-first/1.1.1: - resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} /ejs/3.1.7: resolution: {integrity: sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==} @@ -10286,17 +10632,25 @@ packages: jake: 10.8.5 dev: true - /electron-builder/23.0.3: - resolution: {integrity: sha512-0lnTsljAgcOMuIiOjPcoFf+WxOOe/O04hZPgIvvUBXIbz3kolbNu0Xdch1f5WuQ40NdeZI7oqs8Eo395PcuGHQ==} + /ejs/3.1.8: + resolution: {integrity: sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + jake: 10.8.5 + dev: true + + /electron-builder/23.3.1: + resolution: {integrity: sha512-NYM3iHuX7NyXvbZ+7BKDET54mXnB2oqshuZpe0QbDtbDp6UjoXAulO5g6YXtWA6OspdaTHio+BFpe7A88l1sHg==} engines: {node: '>=14.0.0'} hasBin: true dependencies: '@types/yargs': 17.0.10 - app-builder-lib: 23.0.3 - builder-util: 23.0.2 - builder-util-runtime: 9.0.0 + app-builder-lib: 23.3.1 + builder-util: 23.3.0 + builder-util-runtime: 9.0.3 chalk: 4.1.2 - dmg-builder: 23.0.3 + dmg-builder: 23.3.1 fs-extra: 10.1.0 is-ci: 3.0.1 lazy-val: 1.0.5 @@ -10316,8 +10670,8 @@ packages: unzip-crx-3: 0.2.0 dev: true - /electron-log/4.4.7: - resolution: {integrity: sha512-uFZQdgevOp9Fn5lDOrJMU/bmmYxDLZitbIHJM7VXN+cpB59ZnPt1FQL4bOf/Dl2gaIMPYJEfXx38GvJma5iV6A==} + /electron-log/4.4.8: + resolution: {integrity: sha512-QQ4GvrXO+HkgqqEOYbi+DHL7hj5JM+nHi/j+qrN9zeeXVKy8ZABgbu4CnG+BBqDZ2+tbeq9tUC4DZfIWFU5AZA==} dev: false /electron-osx-sign/0.6.0: @@ -10330,17 +10684,17 @@ packages: debug: 2.6.9 isbinaryfile: 3.0.3 minimist: 1.2.6 - plist: 3.0.5 + plist: 3.0.6 transitivePeerDependencies: - supports-color dev: true - /electron-publish/23.0.2: - resolution: {integrity: sha512-8gMYgWqv96lc83FCm85wd+tEyxNTJQK7WKyPkNkO8GxModZqt1GO8S+/vAnFGxilS/7vsrVRXFfqiCDUCSuxEg==} + /electron-publish/23.3.0: + resolution: {integrity: sha512-HTKOeRUDebSD/l6grAi5thWb/f80OggL1z4aI0no7Fa4SGWpl4rvqlMBtY2d/EjsAAosbk3x+Jeyyp5Th57Wpw==} dependencies: '@types/fs-extra': 9.0.13 - builder-util: 23.0.2 - builder-util-runtime: 9.0.0 + builder-util: 23.3.0 + builder-util-runtime: 9.0.3 chalk: 4.1.2 fs-extra: 10.1.0 lazy-val: 1.0.5 @@ -10349,21 +10703,21 @@ packages: - supports-color dev: true - /electron-rebuild/3.2.7: - resolution: {integrity: sha512-WvaW1EgRinDQ61khHFZfx30rkPQG5ItaOT0wrI7iJv9A3SbghriQGfZQfHZs25fWLBe6/vkv05LOqg6aDw6Wzw==} + /electron-rebuild/3.2.8: + resolution: {integrity: sha512-+U/G5ZH9RNfvPQsEHevC3yDlgSB+wliNXnG6haqUeZBEq061pEgSTWK9ZBEfqMEq+PKxvniMNxfou/h6079s3A==} engines: {node: '>=12.13.0'} hasBin: true dependencies: '@malept/cross-spawn-promise': 2.0.0 chalk: 4.1.2 debug: 4.3.4 - detect-libc: 1.0.3 + detect-libc: 2.0.1 fs-extra: 10.1.0 got: 11.8.3 lzma-native: 8.0.6 node-abi: 3.15.0 node-api-version: 0.1.4 - node-gyp: 8.4.1 + node-gyp: 9.1.0 ora: 5.4.1 semver: 7.3.7 tar: 6.1.11 @@ -10373,23 +10727,23 @@ packages: - supports-color dev: true - /electron-releases/3.1026.0: - resolution: {integrity: sha512-wfPdn1jVOPCOnEg6sVdLKTU4j+3Yf6beDlHQEswBxiVj/vICV7pGWJG4xfxlFRRgUkuNrEayLRa+5mkVNogZgA==} + /electron-releases/3.1072.0: + resolution: {integrity: sha512-njLr+E/uSMkyRJtbF1eJsEBnFsDevCLXhpHqjBh6k18dd5vDiPGN9AyZUZP2Xb+ZzU0dtLBycjAWiAO1WjwWMg==} dev: true - /electron-store/8.0.1: - resolution: {integrity: sha512-ZyLvNywiqSpbwC/pp89O/AycVWY/UJIkmtyzF2Bd0Nm/rLmcFc0NTGuLdg6+LE8mS8qsiK5JMoe4PnrecLHH5w==} + /electron-store/8.0.2: + resolution: {integrity: sha512-9GwUMv51w8ydbkaG7X0HrPlElXLApg63zYy1/VZ/a08ndl0gfm4iCoD3f0E1JvP3V16a+7KxqriCI0c122stiA==} dependencies: conf: 10.1.2 - type-fest: 1.4.0 + type-fest: 2.16.0 dev: false /electron-to-chromium/1.4.137: resolution: {integrity: sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==} dev: true - /electron/19.0.3: - resolution: {integrity: sha512-V/8pFkXUOsoHcBzuTYVSbIQKLIwI/FAxfpvbkMazdaO/weZoIf9AN3Qc4Wuo9+489mhelDYc8lSX5N7c6A5n6A==} + /electron/19.0.8: + resolution: {integrity: sha512-OWK3P/NbDFfBUv+wbYv1/OV4jehY5DQPT7n1maQJfN9hsnrWTMktXS/bmS05eSUAjNAzHmKPKfiKH2c1Yr7nGw==} engines: {node: '>= 8.6'} hasBin: true requiresBuild: true @@ -10621,23 +10975,14 @@ packages: resolution: {integrity: sha512-EmTr31wppcaIAgblChZiuN/l9Y7DPyw8Xtbg7fIVngn6zMW+IEBJDJngeKC3x6wr0V/vcA2wqeFnaw1bFJbDdA==} dev: true - /esbuild-android-64/0.14.38: - resolution: {integrity: sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw==} + /esbuild-android-64/0.14.49: + resolution: {integrity: sha512-vYsdOTD+yi+kquhBiFWl3tyxnj2qZJsl4tAqwhT90ktUdnyTizgle7TjNx6Ar1bN7wcwWqZ9QInfdk2WVagSww==} engines: {node: '>=12'} cpu: [x64] os: [android] requiresBuild: true optional: true - /esbuild-android-64/0.14.42: - resolution: {integrity: sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - /esbuild-android-arm64/0.13.8: resolution: {integrity: sha512-AilbChndywpk7CdKkNSZ9klxl+9MboLctXd9LwLo3b0dawmOF/i/t2U5d8LM6SbT1Xw36F8yngSUPrd8yPs2RA==} cpu: [arm64] @@ -10646,23 +10991,14 @@ packages: dev: true optional: true - /esbuild-android-arm64/0.14.38: - resolution: {integrity: sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA==} + /esbuild-android-arm64/0.14.49: + resolution: {integrity: sha512-g2HGr/hjOXCgSsvQZ1nK4nW/ei8JUx04Li74qub9qWrStlysaVmadRyTVuW32FGIpLQyc5sUjjZopj49eGGM2g==} engines: {node: '>=12'} cpu: [arm64] os: [android] requiresBuild: true optional: true - /esbuild-android-arm64/0.14.42: - resolution: {integrity: sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - /esbuild-darwin-64/0.13.8: resolution: {integrity: sha512-b6sdiT84zV5LVaoF+UoMVGJzR/iE2vNUfUDfFQGrm4LBwM/PWXweKpuu6RD9mcyCq18cLxkP6w/LD/w9DtX3ng==} cpu: [x64] @@ -10671,23 +11007,14 @@ packages: dev: true optional: true - /esbuild-darwin-64/0.14.38: - resolution: {integrity: sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA==} + /esbuild-darwin-64/0.14.49: + resolution: {integrity: sha512-3rvqnBCtX9ywso5fCHixt2GBCUsogNp9DjGmvbBohh31Ces34BVzFltMSxJpacNki96+WIcX5s/vum+ckXiLYg==} engines: {node: '>=12'} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /esbuild-darwin-64/0.14.42: - resolution: {integrity: sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - /esbuild-darwin-arm64/0.13.8: resolution: {integrity: sha512-R8YuPiiJayuJJRUBG4H0VwkEKo6AvhJs2m7Tl0JaIer3u1FHHXwGhMxjJDmK+kXwTFPriSysPvcobXC/UrrZCQ==} cpu: [arm64] @@ -10696,23 +11023,14 @@ packages: dev: true optional: true - /esbuild-darwin-arm64/0.14.38: - resolution: {integrity: sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ==} + /esbuild-darwin-arm64/0.14.49: + resolution: {integrity: sha512-XMaqDxO846srnGlUSJnwbijV29MTKUATmOLyQSfswbK/2X5Uv28M9tTLUJcKKxzoo9lnkYPsx2o8EJcTYwCs/A==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /esbuild-darwin-arm64/0.14.42: - resolution: {integrity: sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - /esbuild-freebsd-64/0.13.8: resolution: {integrity: sha512-zBn6urrn8FnKC+YSgDxdof9jhPCeU8kR/qaamlV4gI8R3KUaUK162WYM7UyFVAlj9N0MyD3AtB+hltzu4cysTw==} cpu: [x64] @@ -10721,23 +11039,14 @@ packages: dev: true optional: true - /esbuild-freebsd-64/0.14.38: - resolution: {integrity: sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig==} + /esbuild-freebsd-64/0.14.49: + resolution: {integrity: sha512-NJ5Q6AjV879mOHFri+5lZLTp5XsO2hQ+KSJYLbfY9DgCu8s6/Zl2prWXVANYTeCDLlrIlNNYw8y34xqyLDKOmQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] requiresBuild: true optional: true - /esbuild-freebsd-64/0.14.42: - resolution: {integrity: sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - /esbuild-freebsd-arm64/0.13.8: resolution: {integrity: sha512-pWW2slN7lGlkx0MOEBoUGwRX5UgSCLq3dy2c8RIOpiHtA87xAUpDBvZK10MykbT+aMfXc0NI2lu1X+6kI34xng==} cpu: [arm64] @@ -10746,23 +11055,14 @@ packages: dev: true optional: true - /esbuild-freebsd-arm64/0.14.38: - resolution: {integrity: sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ==} + /esbuild-freebsd-arm64/0.14.49: + resolution: {integrity: sha512-lFLtgXnAc3eXYqj5koPlBZvEbBSOSUbWO3gyY/0+4lBdRqELyz4bAuamHvmvHW5swJYL7kngzIZw6kdu25KGOA==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] requiresBuild: true optional: true - /esbuild-freebsd-arm64/0.14.42: - resolution: {integrity: sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - /esbuild-linux-32/0.13.8: resolution: {integrity: sha512-T0I0ueeKVO/Is0CAeSEOG9s2jeNNb8jrrMwG9QBIm3UU18MRB60ERgkS2uV3fZ1vP2F8i3Z2e3Zju4lg9dhVmw==} cpu: [ia32] @@ -10771,23 +11071,14 @@ packages: dev: true optional: true - /esbuild-linux-32/0.14.38: - resolution: {integrity: sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g==} + /esbuild-linux-32/0.14.49: + resolution: {integrity: sha512-zTTH4gr2Kb8u4QcOpTDVn7Z8q7QEIvFl/+vHrI3cF6XOJS7iEI1FWslTo3uofB2+mn6sIJEQD9PrNZKoAAMDiA==} engines: {node: '>=12'} cpu: [ia32] os: [linux] requiresBuild: true optional: true - /esbuild-linux-32/0.14.42: - resolution: {integrity: sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - /esbuild-linux-64/0.13.8: resolution: {integrity: sha512-Bm8SYmFtvfDCIu9sjKppFXzRXn2BVpuCinU1ChTuMtdKI/7aPpXIrkqBNOgPTOQO9AylJJc1Zw6EvtKORhn64w==} cpu: [x64] @@ -10796,23 +11087,14 @@ packages: dev: true optional: true - /esbuild-linux-64/0.14.38: - resolution: {integrity: sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q==} + /esbuild-linux-64/0.14.49: + resolution: {integrity: sha512-hYmzRIDzFfLrB5c1SknkxzM8LdEUOusp6M2TnuQZJLRtxTgyPnZZVtyMeCLki0wKgYPXkFsAVhi8vzo2mBNeTg==} engines: {node: '>=12'} cpu: [x64] os: [linux] requiresBuild: true optional: true - /esbuild-linux-64/0.14.42: - resolution: {integrity: sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /esbuild-linux-arm/0.13.8: resolution: {integrity: sha512-4/HfcC40LJ4GPyboHA+db0jpFarTB628D1ifU+/5bunIgY+t6mHkJWyxWxAAE8wl/ZIuRYB9RJFdYpu1AXGPdg==} cpu: [arm] @@ -10821,23 +11103,14 @@ packages: dev: true optional: true - /esbuild-linux-arm/0.14.38: - resolution: {integrity: sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA==} + /esbuild-linux-arm/0.14.49: + resolution: {integrity: sha512-iE3e+ZVv1Qz1Sy0gifIsarJMQ89Rpm9mtLSRtG3AH0FPgAzQ5Z5oU6vYzhc/3gSPi2UxdCOfRhw2onXuFw/0lg==} engines: {node: '>=12'} cpu: [arm] os: [linux] requiresBuild: true optional: true - /esbuild-linux-arm/0.14.42: - resolution: {integrity: sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - /esbuild-linux-arm64/0.13.8: resolution: {integrity: sha512-X4pWZ+SL+FJ09chWFgRNO3F+YtvAQRcWh0uxKqZSWKiWodAB20flsW/OWFYLXBKiVCTeoGMvENZS/GeVac7+tQ==} cpu: [arm64] @@ -10846,23 +11119,14 @@ packages: dev: true optional: true - /esbuild-linux-arm64/0.14.38: - resolution: {integrity: sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA==} + /esbuild-linux-arm64/0.14.49: + resolution: {integrity: sha512-KLQ+WpeuY+7bxukxLz5VgkAAVQxUv67Ft4DmHIPIW+2w3ObBPQhqNoeQUHxopoW/aiOn3m99NSmSV+bs4BSsdA==} engines: {node: '>=12'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /esbuild-linux-arm64/0.14.42: - resolution: {integrity: sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /esbuild-linux-mips64le/0.13.8: resolution: {integrity: sha512-o7e0D+sqHKT31v+mwFircJFjwSKVd2nbkHEn4l9xQ1hLR+Bv8rnt3HqlblY3+sBdlrOTGSwz0ReROlKUMJyldA==} cpu: [mips64el] @@ -10871,23 +11135,14 @@ packages: dev: true optional: true - /esbuild-linux-mips64le/0.14.38: - resolution: {integrity: sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ==} + /esbuild-linux-mips64le/0.14.49: + resolution: {integrity: sha512-n+rGODfm8RSum5pFIqFQVQpYBw+AztL8s6o9kfx7tjfK0yIGF6tm5HlG6aRjodiiKkH2xAiIM+U4xtQVZYU4rA==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] requiresBuild: true optional: true - /esbuild-linux-mips64le/0.14.42: - resolution: {integrity: sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - /esbuild-linux-ppc64le/0.13.8: resolution: {integrity: sha512-eZSQ0ERsWkukJp2px/UWJHVNuy0lMoz/HZcRWAbB6reoaBw7S9vMzYNUnflfL3XA6WDs+dZn3ekHE4Y2uWLGig==} cpu: [ppc64] @@ -10896,57 +11151,30 @@ packages: dev: true optional: true - /esbuild-linux-ppc64le/0.14.38: - resolution: {integrity: sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q==} + /esbuild-linux-ppc64le/0.14.49: + resolution: {integrity: sha512-WP9zR4HX6iCBmMFH+XHHng2LmdoIeUmBpL4aL2TR8ruzXyT4dWrJ5BSbT8iNo6THN8lod6GOmYDLq/dgZLalGw==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] requiresBuild: true optional: true - /esbuild-linux-ppc64le/0.14.42: - resolution: {integrity: sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-riscv64/0.14.38: - resolution: {integrity: sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ==} + /esbuild-linux-riscv64/0.14.49: + resolution: {integrity: sha512-h66ORBz+Dg+1KgLvzTVQEA1LX4XBd1SK0Fgbhhw4akpG/YkN8pS6OzYI/7SGENiN6ao5hETRDSkVcvU9NRtkMQ==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] requiresBuild: true optional: true - /esbuild-linux-riscv64/0.14.42: - resolution: {integrity: sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /esbuild-linux-s390x/0.14.38: - resolution: {integrity: sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ==} + /esbuild-linux-s390x/0.14.49: + resolution: {integrity: sha512-DhrUoFVWD+XmKO1y7e4kNCqQHPs6twz6VV6Uezl/XHYGzM60rBewBF5jlZjG0nCk5W/Xy6y1xWeopkrhFFM0sQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] requiresBuild: true optional: true - /esbuild-linux-s390x/0.14.42: - resolution: {integrity: sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - /esbuild-netbsd-64/0.13.8: resolution: {integrity: sha512-gZX4kP7gVvOrvX0ZwgHmbuHczQUwqYppxqtoyC7VNd80t5nBHOFXVhWo2Ad/Lms0E8b+wwgI/WjZFTCpUHOg9Q==} cpu: [x64] @@ -10955,23 +11183,14 @@ packages: dev: true optional: true - /esbuild-netbsd-64/0.14.38: - resolution: {integrity: sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q==} + /esbuild-netbsd-64/0.14.49: + resolution: {integrity: sha512-BXaUwFOfCy2T+hABtiPUIpWjAeWK9P8O41gR4Pg73hpzoygVGnj0nI3YK4SJhe52ELgtdgWP/ckIkbn2XaTxjQ==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] requiresBuild: true optional: true - /esbuild-netbsd-64/0.14.42: - resolution: {integrity: sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - /esbuild-openbsd-64/0.13.8: resolution: {integrity: sha512-afzza308X4WmcebexbTzAgfEWt9MUkdTvwIa8xOu4CM2qGbl2LanqEl8/LUs8jh6Gqw6WsicEK52GPrS9wvkcw==} cpu: [x64] @@ -10980,23 +11199,14 @@ packages: dev: true optional: true - /esbuild-openbsd-64/0.14.38: - resolution: {integrity: sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ==} + /esbuild-openbsd-64/0.14.49: + resolution: {integrity: sha512-lP06UQeLDGmVPw9Rg437Btu6J9/BmyhdoefnQ4gDEJTtJvKtQaUcOQrhjTq455ouZN4EHFH1h28WOJVANK41kA==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] requiresBuild: true optional: true - /esbuild-openbsd-64/0.14.42: - resolution: {integrity: sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - /esbuild-sunos-64/0.13.8: resolution: {integrity: sha512-mWPZibmBbuMKD+LDN23LGcOZ2EawMYBONMXXHmbuxeT0XxCNwadbCVwUQ/2p5Dp5Kvf6mhrlIffcnWOiCBpiVw==} cpu: [x64] @@ -11005,23 +11215,14 @@ packages: dev: true optional: true - /esbuild-sunos-64/0.14.38: - resolution: {integrity: sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA==} + /esbuild-sunos-64/0.14.49: + resolution: {integrity: sha512-4c8Zowp+V3zIWje329BeLbGh6XI9c/rqARNaj5yPHdC61pHI9UNdDxT3rePPJeWcEZVKjkiAS6AP6kiITp7FSw==} engines: {node: '>=12'} cpu: [x64] os: [sunos] requiresBuild: true optional: true - /esbuild-sunos-64/0.14.42: - resolution: {integrity: sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - /esbuild-windows-32/0.13.8: resolution: {integrity: sha512-QsZ1HnWIcnIEApETZWw8HlOhDSWqdZX2SylU7IzGxOYyVcX7QI06ety/aDcn437mwyO7Ph4RrbhB+2ntM8kX8A==} cpu: [ia32] @@ -11030,23 +11231,14 @@ packages: dev: true optional: true - /esbuild-windows-32/0.14.38: - resolution: {integrity: sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw==} + /esbuild-windows-32/0.14.49: + resolution: {integrity: sha512-q7Rb+J9yHTeKr9QTPDYkqfkEj8/kcKz9lOabDuvEXpXuIcosWCJgo5Z7h/L4r7rbtTH4a8U2FGKb6s1eeOHmJA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] requiresBuild: true optional: true - /esbuild-windows-32/0.14.42: - resolution: {integrity: sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - /esbuild-windows-64/0.13.8: resolution: {integrity: sha512-76Fb57B9eE/JmJi1QmUW0tRLQZfGo0it+JeYoCDTSlbTn7LV44ecOHIMJSSgZADUtRMWT9z0Kz186bnaB3amSg==} cpu: [x64] @@ -11055,23 +11247,14 @@ packages: dev: true optional: true - /esbuild-windows-64/0.14.38: - resolution: {integrity: sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw==} + /esbuild-windows-64/0.14.49: + resolution: {integrity: sha512-+Cme7Ongv0UIUTniPqfTX6mJ8Deo7VXw9xN0yJEN1lQMHDppTNmKwAM3oGbD/Vqff+07K2gN0WfNkMohmG+dVw==} engines: {node: '>=12'} cpu: [x64] os: [win32] requiresBuild: true optional: true - /esbuild-windows-64/0.14.42: - resolution: {integrity: sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /esbuild-windows-arm64/0.13.8: resolution: {integrity: sha512-HW6Mtq5eTudllxY2YgT62MrVcn7oq2o8TAoAvDUhyiEmRmDY8tPwAhb1vxw5/cdkbukM3KdMYtksnUhF/ekWeg==} cpu: [arm64] @@ -11080,23 +11263,14 @@ packages: dev: true optional: true - /esbuild-windows-arm64/0.14.38: - resolution: {integrity: sha512-k3FGCNmHBkqdJXuJszdWciAH77PukEyDsdIryEHn9cKLQFxzhT39dSumeTuggaQcXY57UlmLGIkklWZo2qzHpw==} + /esbuild-windows-arm64/0.14.49: + resolution: {integrity: sha512-v+HYNAXzuANrCbbLFJ5nmO3m5y2PGZWLe3uloAkLt87aXiO2mZr3BTmacZdjwNkNEHuH3bNtN8cak+mzVjVPfA==} engines: {node: '>=12'} cpu: [arm64] os: [win32] requiresBuild: true optional: true - /esbuild-windows-arm64/0.14.42: - resolution: {integrity: sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /esbuild/0.13.8: resolution: {integrity: sha512-A4af7G7YZLfG5OnARJRMtlpEsCkq/zHZQXewgPA864l9D6VjjbH1SuFYK/OSV6BtHwDGkdwyRrX0qQFLnMfUcw==} hasBin: true @@ -11121,60 +11295,32 @@ packages: esbuild-windows-arm64: 0.13.8 dev: true - /esbuild/0.14.38: - resolution: {integrity: sha512-12fzJ0fsm7gVZX1YQ1InkOE5f9Tl7cgf6JPYXRJtPIoE0zkWAbHdPHVPPaLi9tYAcEBqheGzqLn/3RdTOyBfcA==} + /esbuild/0.14.49: + resolution: {integrity: sha512-/TlVHhOaq7Yz8N1OJrjqM3Auzo5wjvHFLk+T8pIue+fhnhIMpfAzsG6PLVMbFveVxqD2WOp3QHei+52IMUNmCw==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - esbuild-android-64: 0.14.38 - esbuild-android-arm64: 0.14.38 - esbuild-darwin-64: 0.14.38 - esbuild-darwin-arm64: 0.14.38 - esbuild-freebsd-64: 0.14.38 - esbuild-freebsd-arm64: 0.14.38 - esbuild-linux-32: 0.14.38 - esbuild-linux-64: 0.14.38 - esbuild-linux-arm: 0.14.38 - esbuild-linux-arm64: 0.14.38 - esbuild-linux-mips64le: 0.14.38 - esbuild-linux-ppc64le: 0.14.38 - esbuild-linux-riscv64: 0.14.38 - esbuild-linux-s390x: 0.14.38 - esbuild-netbsd-64: 0.14.38 - esbuild-openbsd-64: 0.14.38 - esbuild-sunos-64: 0.14.38 - esbuild-windows-32: 0.14.38 - esbuild-windows-64: 0.14.38 - esbuild-windows-arm64: 0.14.38 - - /esbuild/0.14.42: - resolution: {integrity: sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - esbuild-android-64: 0.14.42 - esbuild-android-arm64: 0.14.42 - esbuild-darwin-64: 0.14.42 - esbuild-darwin-arm64: 0.14.42 - esbuild-freebsd-64: 0.14.42 - esbuild-freebsd-arm64: 0.14.42 - esbuild-linux-32: 0.14.42 - esbuild-linux-64: 0.14.42 - esbuild-linux-arm: 0.14.42 - esbuild-linux-arm64: 0.14.42 - esbuild-linux-mips64le: 0.14.42 - esbuild-linux-ppc64le: 0.14.42 - esbuild-linux-riscv64: 0.14.42 - esbuild-linux-s390x: 0.14.42 - esbuild-netbsd-64: 0.14.42 - esbuild-openbsd-64: 0.14.42 - esbuild-sunos-64: 0.14.42 - esbuild-windows-32: 0.14.42 - esbuild-windows-64: 0.14.42 - esbuild-windows-arm64: 0.14.42 - dev: true + esbuild-android-64: 0.14.49 + esbuild-android-arm64: 0.14.49 + esbuild-darwin-64: 0.14.49 + esbuild-darwin-arm64: 0.14.49 + esbuild-freebsd-64: 0.14.49 + esbuild-freebsd-arm64: 0.14.49 + esbuild-linux-32: 0.14.49 + esbuild-linux-64: 0.14.49 + esbuild-linux-arm: 0.14.49 + esbuild-linux-arm64: 0.14.49 + esbuild-linux-mips64le: 0.14.49 + esbuild-linux-ppc64le: 0.14.49 + esbuild-linux-riscv64: 0.14.49 + esbuild-linux-s390x: 0.14.49 + esbuild-netbsd-64: 0.14.49 + esbuild-openbsd-64: 0.14.49 + esbuild-sunos-64: 0.14.49 + esbuild-windows-32: 0.14.49 + esbuild-windows-64: 0.14.49 + esbuild-windows-arm64: 0.14.49 /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} @@ -11189,7 +11335,7 @@ packages: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} /escape-string-regexp/1.0.5: - resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} /escape-string-regexp/4.0.0: @@ -11288,6 +11434,16 @@ packages: eslint-visitor-keys: 2.1.0 dev: true + /eslint-utils/3.0.0_eslint@8.20.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.20.0 + eslint-visitor-keys: 2.1.0 + dev: true + /eslint-visitor-keys/2.1.0: resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} engines: {node: '>=10'} @@ -11342,6 +11498,50 @@ packages: - supports-color dev: true + /eslint/8.20.0: + resolution: {integrity: sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint/eslintrc': 1.3.0 + '@humanwhocodes/config-array': 0.9.5 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.1 + eslint-utils: 3.0.0_eslint@8.20.0 + eslint-visitor-keys: 3.3.0 + espree: 9.3.2 + esquery: 1.4.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 6.0.2 + globals: 13.15.0 + ignore: 5.2.0 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + regexpp: 3.2.0 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + v8-compile-cache: 2.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /espree/9.3.2: resolution: {integrity: sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -11403,9 +11603,21 @@ packages: engines: {node: '>=0.10.0'} /etag/1.8.1: - resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=} + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + /event-stream/3.3.4: + resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.1.0 + pause-stream: 0.0.11 + split: 0.3.3 + stream-combiner: 0.0.4 + through: 2.3.8 + dev: false + /events/3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -11531,7 +11743,6 @@ packages: /extend/3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: true /extglob/2.0.4: resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} @@ -11601,7 +11812,6 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: true /fast-json-parse/1.0.3: resolution: {integrity: sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==} @@ -11612,7 +11822,7 @@ packages: dev: true /fast-levenshtein/2.0.6: - resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} /fast-shallow-equal/1.0.0: resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==} @@ -11626,7 +11836,6 @@ packages: resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} dependencies: reusify: 1.0.4 - dev: true /fault/1.0.4: resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} @@ -11646,6 +11855,14 @@ packages: pend: 1.2.0 dev: true + /fetch-blob/3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.2.1 + dev: false + /fetch-retry/5.0.2: resolution: {integrity: sha512-57Hmu+1kc6pKFUGVIobT7qw3NeAzY/uNN26bSevERLVvf6VGFR/ooDCOFBHMNDgAxBiU2YJq1D0vFzc6U1DcPw==} dev: true @@ -11695,10 +11912,10 @@ packages: engines: {node: '>= 6'} dev: false - /filelist/1.0.3: - resolution: {integrity: sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q==} + /filelist/1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} dependencies: - minimatch: 5.0.1 + minimatch: 5.1.0 dev: true /fill-range/4.0.0: @@ -11716,7 +11933,6 @@ packages: engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 - dev: true /finalhandler/1.2.0: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} @@ -11913,6 +12129,13 @@ packages: engines: {node: '>=0.4.x'} dev: true + /formdata-polyfill/4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + dependencies: + fetch-blob: 3.2.0 + dev: false + /forwarded/0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -11952,9 +12175,13 @@ packages: dev: false /fresh/0.5.2: - resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + /from/0.1.7: + resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} + dev: false + /from2/2.3.0: resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} dependencies: @@ -11973,7 +12200,6 @@ packages: graceful-fs: 4.2.10 jsonfile: 6.1.0 universalify: 2.0.0 - dev: true /fs-extra/8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} @@ -11997,7 +12223,7 @@ packages: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} dependencies: - minipass: 3.1.6 + minipass: 3.3.4 dev: true /fs-monkey/1.0.3: @@ -12014,7 +12240,7 @@ packages: dev: true /fs.realpath/1.0.0: - resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} /fsevents/1.2.13: resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} @@ -12067,7 +12293,7 @@ packages: dev: true /functional-red-black-tree/1.0.1: - resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} dev: true /functions-have-names/1.2.3: @@ -12075,7 +12301,7 @@ packages: dev: true /gauge/2.7.4: - resolution: {integrity: sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=} + resolution: {integrity: sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==} dependencies: aproba: 1.2.0 console-control-strings: 1.1.0 @@ -12126,7 +12352,7 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} /get-func-name/2.0.0: - resolution: {integrity: sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=} + resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} dev: true /get-intrinsic/1.1.1: @@ -12203,7 +12429,7 @@ packages: dev: true /github-from-package/0.0.0: - resolution: {integrity: sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=} + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} dev: false /github-slugger/1.4.0: @@ -12222,7 +12448,6 @@ packages: engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 - dev: true /glob-parent/6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} @@ -12268,6 +12493,7 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + dev: true /glob/7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -12279,6 +12505,17 @@ packages: once: 1.4.0 path-is-absolute: 1.0.1 + /glob/8.0.3: + resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==} + engines: {node: '>=12'} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.0 + once: 1.4.0 + dev: true + /global-agent/3.0.0: resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} engines: {node: '>=10.0'} @@ -12349,6 +12586,17 @@ packages: slash: 3.0.0 dev: true + /globby/13.1.2: + resolution: {integrity: sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.2.11 + ignore: 5.2.0 + merge2: 1.4.1 + slash: 4.0.0 + dev: false + /globby/9.2.0: resolution: {integrity: sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==} engines: {node: '>=6'} @@ -12411,7 +12659,7 @@ packages: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} /graceful-readlink/1.0.1: - resolution: {integrity: sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=} + resolution: {integrity: sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==} dev: true /handlebars/4.7.7: @@ -12449,7 +12697,7 @@ packages: dev: true /has-flag/3.0.0: - resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} /has-flag/4.0.0: @@ -12482,7 +12730,7 @@ packages: dev: true /has-unicode/2.0.1: - resolution: {integrity: sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=} + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} /has-value/0.3.1: resolution: {integrity: sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=} @@ -12766,6 +13014,7 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color + dev: false /http-proxy-agent/5.0.0: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} @@ -12805,7 +13054,7 @@ packages: dev: true /humanize-ms/1.2.1: - resolution: {integrity: sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=} + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} dependencies: ms: 2.1.3 dev: true @@ -12863,7 +13112,6 @@ packages: /ignore/5.2.0: resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} engines: {node: '>= 4'} - dev: true /image-size/0.5.5: resolution: {integrity: sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=} @@ -12872,7 +13120,7 @@ packages: dev: true /immediate/3.0.6: - resolution: {integrity: sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=} + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} dev: true /import-fresh/3.3.0: @@ -12883,12 +13131,12 @@ packages: resolve-from: 4.0.0 /import-lazy/2.1.0: - resolution: {integrity: sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=} + resolution: {integrity: sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==} engines: {node: '>=4'} dev: true /imurmurhash/0.1.4: - resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=} + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} dev: true @@ -12915,7 +13163,7 @@ packages: dev: true /inflight/1.0.6: - resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: once: 1.4.0 wrappy: 1.0.2 @@ -12970,6 +13218,9 @@ packages: /ip/1.1.8: resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==} + /ip/2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + /ipaddr.js/1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -13013,7 +13264,7 @@ packages: dev: true /is-arrayish/0.2.1: - resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=} + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} /is-bigint/1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} @@ -13145,9 +13396,8 @@ packages: dev: true /is-extglob/2.1.1: - resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - dev: true /is-finite/1.1.0: resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} @@ -13156,7 +13406,7 @@ packages: optional: true /is-fullwidth-code-point/1.0.0: - resolution: {integrity: sha1-754xOG8DGn8NZDr4L95QxFfvAMs=} + resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} engines: {node: '>=0.10.0'} dependencies: number-is-nan: 1.0.1 @@ -13182,7 +13432,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - dev: true /is-hexadecimal/1.0.4: resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} @@ -13207,7 +13456,7 @@ packages: dev: true /is-lambda/1.0.1: - resolution: {integrity: sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=} + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} dev: true /is-map/2.0.2: @@ -13245,7 +13494,6 @@ packages: /is-number/7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - dev: true /is-obj/1.0.1: resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} @@ -13271,7 +13519,7 @@ packages: dev: true /is-plain-obj/1.1.0: - resolution: {integrity: sha1-caUMhCnfync8kqOQpKA7OfzVHT4=} + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} dev: true @@ -13344,7 +13592,7 @@ packages: dev: true /is-typedarray/1.0.0: - resolution: {integrity: sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=} + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} dev: true /is-unicode-supported/0.1.0: @@ -13402,11 +13650,11 @@ packages: dev: true /isarray/0.0.1: - resolution: {integrity: sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=} + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} dev: false /isarray/1.0.0: - resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} /isarray/2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -13425,8 +13673,7 @@ packages: dev: true /isexe/2.0.0: - resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} - dev: true + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} /isobject/2.1.0: resolution: {integrity: sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=} @@ -13504,9 +13751,9 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - async: 3.2.3 + async: 3.2.4 chalk: 4.1.2 - filelist: 1.0.3 + filelist: 1.0.4 minimatch: 3.1.2 dev: true @@ -13607,12 +13854,8 @@ packages: engines: {node: '>=12'} dev: false - /js-sha3/0.8.0: - resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} - dev: false - /js-string-escape/1.0.1: - resolution: {integrity: sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=} + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} engines: {node: '>= 0.8'} dev: true @@ -13688,7 +13931,7 @@ packages: dev: true /json-buffer/3.0.0: - resolution: {integrity: sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=} + resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} dev: true /json-buffer/3.0.1: @@ -13718,11 +13961,11 @@ packages: dev: true /json-stable-stringify-without-jsonify/1.0.1: - resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true /json-stringify-safe/5.0.1: - resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=} + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} dev: true optional: true @@ -13740,7 +13983,7 @@ packages: dev: true /jsonfile/4.0.0: - resolution: {integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=} + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: graceful-fs: 4.2.10 @@ -13750,7 +13993,6 @@ packages: universalify: 2.0.0 optionalDependencies: graceful-fs: 4.2.10 - dev: true /jsonpointer/5.0.0: resolution: {integrity: sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg==} @@ -13854,7 +14096,7 @@ packages: dev: true /levn/0.3.0: - resolution: {integrity: sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=} + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.1.2 @@ -13883,7 +14125,7 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} /listenercount/1.0.1: - resolution: {integrity: sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=} + resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==} dev: false /load-json-file/1.1.0: @@ -13994,6 +14236,10 @@ packages: is-unicode-supported: 1.2.0 dev: true + /long/4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + dev: false + /loose-envify/1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -14049,8 +14295,13 @@ packages: dependencies: yallist: 4.0.0 + /lru-cache/7.13.1: + resolution: {integrity: sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ==} + engines: {node: '>=12'} + dev: true + /lru_map/0.3.3: - resolution: {integrity: sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=} + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} dev: false /lz-string/1.4.4: @@ -14105,26 +14356,26 @@ packages: semver: 6.3.0 dev: true - /make-fetch-happen/9.1.0: - resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==} - engines: {node: '>= 10'} + /make-fetch-happen/10.1.8: + resolution: {integrity: sha512-0ASJbG12Au6+N5I84W+8FhGS6iM8MyzvZady+zaQAu+6IOaESFzCLLD0AR1sAFF3Jufi8bxm586ABN6hWd3k7g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} dependencies: agentkeepalive: 4.2.1 - cacache: 15.3.0 + cacache: 16.1.1 http-cache-semantics: 4.1.0 - http-proxy-agent: 4.0.1 + http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 is-lambda: 1.0.1 - lru-cache: 6.0.0 - minipass: 3.1.6 + lru-cache: 7.13.1 + minipass: 3.3.4 minipass-collect: 1.0.2 - minipass-fetch: 1.4.1 + minipass-fetch: 2.1.0 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 negotiator: 0.6.3 promise-retry: 2.0.1 - socks-proxy-agent: 6.2.0 - ssri: 8.0.1 + socks-proxy-agent: 7.0.0 + ssri: 9.0.1 transitivePeerDependencies: - bluebird - supports-color @@ -14142,7 +14393,7 @@ packages: dev: true /map-obj/1.0.1: - resolution: {integrity: sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=} + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} dev: true @@ -14155,6 +14406,10 @@ packages: resolution: {integrity: sha1-beJlMXSt+12e3DPGnT6Sobdvrwg=} dev: true + /map-stream/0.1.0: + resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} + dev: false + /map-visit/1.0.0: resolution: {integrity: sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=} engines: {node: '>=0.10.0'} @@ -14166,13 +14421,6 @@ packages: resolution: {integrity: sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==} dev: true - /match-sorter/6.3.1: - resolution: {integrity: sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==} - dependencies: - '@babel/runtime': 7.18.3 - remove-accents: 0.4.2 - dev: false - /matcher/3.0.0: resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} engines: {node: '>=10'} @@ -14234,7 +14482,7 @@ packages: dev: true /media-typer/0.3.0: - resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} /media-typer/1.1.0: @@ -14305,7 +14553,7 @@ packages: optional: true /merge-descriptors/1.0.1: - resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=} + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} /merge-options/1.0.1: resolution: {integrity: sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==} @@ -14321,10 +14569,9 @@ packages: /merge2/1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - dev: true /methods/1.1.2: - resolution: {integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=} + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} /microevent.ts/0.1.1: @@ -14379,11 +14626,6 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: true - - /microseconds/0.2.0: - resolution: {integrity: sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==} - dev: false /miller-rabin/4.0.1: resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} @@ -14414,6 +14656,12 @@ packages: hasBin: true dev: true + /mime/3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + dev: false + /mimic-fn/2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -14461,8 +14709,8 @@ packages: dependencies: brace-expansion: 1.1.11 - /minimatch/5.0.1: - resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + /minimatch/5.1.0: + resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 @@ -14484,14 +14732,14 @@ packages: resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} engines: {node: '>= 8'} dependencies: - minipass: 3.1.6 + minipass: 3.3.4 dev: true - /minipass-fetch/1.4.1: - resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==} - engines: {node: '>=8'} + /minipass-fetch/2.1.0: + resolution: {integrity: sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} dependencies: - minipass: 3.1.6 + minipass: 3.3.4 minipass-sized: 1.0.3 minizlib: 2.1.2 optionalDependencies: @@ -14502,21 +14750,21 @@ packages: resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} engines: {node: '>= 8'} dependencies: - minipass: 3.1.6 + minipass: 3.3.4 dev: true /minipass-pipeline/1.2.4: resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} engines: {node: '>=8'} dependencies: - minipass: 3.1.6 + minipass: 3.3.4 dev: true /minipass-sized/1.0.3: resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} engines: {node: '>=8'} dependencies: - minipass: 3.1.6 + minipass: 3.3.4 dev: true /minipass/3.1.6: @@ -14526,11 +14774,18 @@ packages: yallist: 4.0.0 dev: true + /minipass/3.3.4: + resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: true + /minizlib/2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} dependencies: - minipass: 3.1.6 + minipass: 3.3.4 yallist: 4.0.0 dev: true @@ -14591,7 +14846,7 @@ packages: dev: true /ms/2.0.0: - resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} /ms/2.1.1: resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} @@ -14603,8 +14858,16 @@ packages: /ms/2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - /music-metadata/7.12.3: - resolution: {integrity: sha512-6pZngaroNxGBf8KZjE8reGZJiS533eJq7dBFsyoiEAZIORQAxmVVx20ABh9W2tsLT+5mKYyDzcNi5GuHf3jitg==} + /multicast-dns/7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + dependencies: + dns-packet: 5.4.0 + thunky: 1.1.0 + dev: false + + /music-metadata/7.12.4: + resolution: {integrity: sha512-hn4DsDYQUeq4WDDh7MD/nSj6CaZMywuD/4Ywq6veeh4Q5KZw4A2yLY8gUzsEWf/ctdtV9Lj066ihkU7Nk7EXIA==} engines: {node: '>=10'} dependencies: '@tokenizer/token': 0.3.0 @@ -14640,12 +14903,6 @@ packages: stylis: 4.1.1 dev: false - /nano-time/1.0.0: - resolution: {integrity: sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=} - dependencies: - big-integer: 1.6.51 - dev: false - /nanoid/3.3.4: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -14675,9 +14932,21 @@ packages: dev: false /natural-compare/1.4.0: - resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true + /needle/2.9.1: + resolution: {integrity: sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==} + engines: {node: '>= 4.4.x'} + hasBin: true + dependencies: + debug: 3.2.7 + iconv-lite: 0.4.24 + sax: 1.2.4 + transitivePeerDependencies: + - supports-color + dev: false + /negotiator/0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -14733,6 +15002,11 @@ packages: minimatch: 3.1.2 dev: true + /node-domexception/1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + dev: false + /node-fetch/2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -14745,20 +15019,29 @@ packages: whatwg-url: 5.0.0 dev: true + /node-fetch/3.2.9: + resolution: {integrity: sha512-/2lI+DBecVvVm9tDhjziTVjo2wmTsSxSk58saUYP0P/fRJ3xxtfMDY24+CKTkfm0Dlhyn3CSXNL0SoRiCZ8Rzg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + data-uri-to-buffer: 4.0.0 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + dev: false + /node-gyp-build/4.4.0: resolution: {integrity: sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==} hasBin: true dev: true - /node-gyp/8.4.1: - resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} - engines: {node: '>= 10.12.0'} + /node-gyp/9.1.0: + resolution: {integrity: sha512-HkmN0ZpQJU7FLbJauJTHkHlSVAXlNGDAzH/VYFZGDOnFyn/Na3GlNJfkudmufOdS6/jNFhy88ObzL7ERz9es1g==} + engines: {node: ^12.22 || ^14.13 || >=16} hasBin: true dependencies: env-paths: 2.2.1 - glob: 7.2.0 + glob: 7.2.3 graceful-fs: 4.2.10 - make-fetch-happen: 9.1.0 + make-fetch-happen: 10.1.8 nopt: 5.0.0 npmlog: 6.0.2 rimraf: 3.0.2 @@ -14806,6 +15089,19 @@ packages: resolution: {integrity: sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==} dev: true + /node-ssdp/4.0.1: + resolution: {integrity: sha512-uJXkLZVuyaMg1qNbMbGQ6YzNzyOD+NLxYyxIJocPTKTVECPDokOiCZA686jTLXHMUnV34uY/lcUSJ+/5fhY43A==} + engines: {node: '>=0.10.0'} + dependencies: + async: 2.6.4 + bluebird: 3.7.2 + debug: 3.2.7 + extend: 3.0.2 + ip: 1.1.8 + transitivePeerDependencies: + - supports-color + dev: false + /nopt/5.0.0: resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} engines: {node: '>=6'} @@ -14922,7 +15218,7 @@ packages: dev: true /number-is-nan/1.0.1: - resolution: {integrity: sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=} + resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} engines: {node: '>=0.10.0'} dev: false @@ -14931,7 +15227,7 @@ packages: dev: true /object-assign/4.1.1: - resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=} + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} /object-copy/0.1.0: @@ -14950,10 +15246,10 @@ packages: /object-inspect/1.12.0: resolution: {integrity: sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==} + dev: true /object-inspect/1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} - dev: true /object-keys/1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} @@ -15032,10 +15328,6 @@ packages: resolution: {integrity: sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==} dev: true - /oblivious-set/1.0.0: - resolution: {integrity: sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==} - dev: false - /on-finished/2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -15048,7 +15340,7 @@ packages: dev: true /once/1.4.0: - resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 @@ -15125,8 +15417,8 @@ packages: wcwidth: 1.0.1 dev: true - /ora/6.1.0: - resolution: {integrity: sha512-CxEP6845hLK+NHFWZ+LplGO4zfw4QSfxTlqMfvlJ988GoiUeZDMzCvqsZkFHv69sPICmJH1MDxZoQFOKXerAVw==} + /ora/6.1.2: + resolution: {integrity: sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: bl: 5.0.0 @@ -15389,7 +15681,7 @@ packages: optional: true /path-exists/3.0.0: - resolution: {integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=} + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} /path-exists/4.0.0: @@ -15397,7 +15689,7 @@ packages: engines: {node: '>=8'} /path-is-absolute/1.0.1: - resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} /path-key/2.0.1: @@ -15414,7 +15706,7 @@ packages: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} /path-to-regexp/0.1.7: - resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=} + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} /path-type/1.1.0: resolution: {integrity: sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=} @@ -15445,6 +15737,12 @@ packages: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true + /pause-stream/0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + dependencies: + through: 2.3.8 + dev: false + /pbkdf2/3.1.2: resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} engines: {node: '>=0.12'} @@ -15461,7 +15759,7 @@ packages: engines: {node: '>=8'} /pend/1.2.0: - resolution: {integrity: sha1-elfrVQpng/kRUzH89GY9XI4AelA=} + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} dev: true /picocolors/0.2.1: @@ -15474,7 +15772,6 @@ packages: /picomatch/2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - dev: true /pify/2.3.0: resolution: {integrity: sha1-7RQaasBDqEnqWISY59yosVMw6Qw=} @@ -15483,7 +15780,7 @@ packages: optional: true /pify/3.0.0: - resolution: {integrity: sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=} + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} dev: true @@ -15539,12 +15836,12 @@ packages: find-up: 3.0.0 dev: false - /plist/3.0.5: - resolution: {integrity: sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==} + /plist/3.0.6: + resolution: {integrity: sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==} engines: {node: '>=6'} dependencies: base64-js: 1.5.1 - xmlbuilder: 9.0.7 + xmlbuilder: 15.1.1 dev: true /plyr-react/5.0.2_react@18.1.0: @@ -15814,7 +16111,7 @@ packages: dev: false /prelude-ls/1.1.2: - resolution: {integrity: sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=} + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} engines: {node: '>= 0.8.0'} /prelude-ls/1.2.1: @@ -15823,7 +16120,7 @@ packages: dev: true /prepend-http/2.0.0: - resolution: {integrity: sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=} + resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} engines: {node: '>=4'} dev: true @@ -15848,6 +16145,12 @@ packages: hasBin: true dev: true + /prettier/2.7.1: + resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + /pretty-bytes/5.6.0: resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} engines: {node: '>=6'} @@ -15972,10 +16275,30 @@ packages: dev: true /proto-list/1.2.4: - resolution: {integrity: sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=} + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} dev: true optional: true + /protobufjs/6.11.3: + resolution: {integrity: sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==} + hasBin: true + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + '@types/node': 18.0.6 + long: 4.0.0 + dev: false + /proxy-addr/2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -15991,6 +16314,14 @@ packages: resolution: {integrity: sha1-0/wRS6BplaRexok/SEzrHXj19HY=} dev: true + /ps-tree/1.2.0: + resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} + engines: {node: '>= 0.10'} + hasBin: true + dependencies: + event-stream: 3.3.4 + dev: false + /psl/1.8.0: resolution: {integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==} dev: true @@ -16090,7 +16421,6 @@ packages: /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true /quick-lru/5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} @@ -16281,25 +16611,6 @@ packages: resolution: {integrity: sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==} dev: true - /react-query/3.39.1_ef5jwxihqo6n7gxfmzogljlgcm: - resolution: {integrity: sha512-qYKT1bavdDiQZbngWZyPotlBVzcBjDYEJg5RQLBa++5Ix5jjfbEYJmHSZRZD+USVHUSvl/ey9Hu+QfF1QAK80A==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: '*' - react-native: '*' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true - dependencies: - '@babel/runtime': 7.17.9 - broadcast-channel: 3.7.0 - match-sorter: 6.3.1 - react: 18.1.0 - react-dom: 18.1.0_react@18.1.0 - dev: false - /react-refresh/0.11.0: resolution: {integrity: sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==} engines: {node: '>=0.10.0'} @@ -16376,8 +16687,8 @@ packages: tslib: 2.4.0 dev: false - /react-virtuoso/2.16.1_ef5jwxihqo6n7gxfmzogljlgcm: - resolution: {integrity: sha512-WpcHZedUe00XYSQ56KcdYmWy/oaiPPuweTYemC9gl8CbjchLTKqLPCJa51Yv32U9oj1XPAEMfxuaXM7NTtjOiw==} + /react-virtuoso/2.16.5_ef5jwxihqo6n7gxfmzogljlgcm: + resolution: {integrity: sha512-bedbW1eJX/s0/XdDVxYZG1kLwXbLkpASskRQ4+UuvZ3mU0LWqDtjPsEzylXbOGhRaWeiuiG768BGl4zxQUBczg==} engines: {node: '>=10'} peerDependencies: react: '>=16 || >=17 || >= 18' @@ -16464,7 +16775,7 @@ packages: dev: true /readable-stream/1.1.14: - resolution: {integrity: sha1-fPTFTvZI44EwhMY23SB54WbAgdk=} + resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==} dependencies: core-util-is: 1.0.3 inherits: 2.0.4 @@ -16690,7 +17001,7 @@ packages: dev: true /remove-accents/0.4.2: - resolution: {integrity: sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=} + resolution: {integrity: sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==} dev: false /remove-trailing-separator/1.1.0: @@ -16726,7 +17037,7 @@ packages: optional: true /require-directory/2.1.1: - resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} /require-from-string/2.0.2: @@ -16775,7 +17086,7 @@ packages: dev: true /responselike/1.0.2: - resolution: {integrity: sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=} + resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} dependencies: lowercase-keys: 1.0.1 dev: true @@ -16808,14 +17119,13 @@ packages: dev: true /retry/0.12.0: - resolution: {integrity: sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=} + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} dev: true /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true /rimraf/2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} @@ -16827,7 +17137,8 @@ packages: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true dependencies: - glob: 7.2.0 + glob: 7.2.3 + dev: true /ripemd160/2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} @@ -16896,7 +17207,6 @@ packages: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 - dev: true /run-queue/1.0.3: resolution: {integrity: sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=} @@ -16960,7 +17270,6 @@ packages: /sax/1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} - dev: true /saxes/5.0.1: resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} @@ -17016,7 +17325,7 @@ packages: dev: false /semver-compare/1.0.0: - resolution: {integrity: sha1-De4hahyUGrN+nvsXiPavxf9VN/w=} + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} dev: true optional: true @@ -17126,7 +17435,7 @@ packages: - supports-color /set-blocking/2.0.0: - resolution: {integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=} + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} /set-harmonic-interval/1.0.1: resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==} @@ -17134,7 +17443,7 @@ packages: dev: false /set-immediate-shim/1.0.1: - resolution: {integrity: sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=} + resolution: {integrity: sha512-Li5AOqrZWCVA2n5kryzEmqai6bKSIvpz5oUJHPVj6+dsbD3X1ixtsY5tEnsaNpH3pFAHmG8eIHUrtEtohrg+UQ==} engines: {node: '>=0.10.0'} dev: true @@ -17149,7 +17458,7 @@ packages: dev: true /setimmediate/1.0.5: - resolution: {integrity: sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=} + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} /setprototypeof/1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -17198,7 +17507,7 @@ packages: dependencies: call-bind: 1.0.2 get-intrinsic: 1.1.1 - object-inspect: 1.12.0 + object-inspect: 1.12.2 /signal-exit/3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -17238,6 +17547,11 @@ packages: engines: {node: '>=8'} dev: true + /slash/4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: false + /slice-ansi/3.0.0: resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} engines: {node: '>=8'} @@ -17297,27 +17611,27 @@ packages: dependencies: agent-base: 6.0.2 debug: 4.3.4 - socks: 2.6.2 + socks: 2.7.0 transitivePeerDependencies: - supports-color dev: false - /socks-proxy-agent/6.2.0: - resolution: {integrity: sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==} + /socks-proxy-agent/7.0.0: + resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} engines: {node: '>= 10'} dependencies: agent-base: 6.0.2 debug: 4.3.4 - socks: 2.6.2 + socks: 2.7.0 transitivePeerDependencies: - supports-color dev: true - /socks/2.6.2: - resolution: {integrity: sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==} + /socks/2.7.0: + resolution: {integrity: sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==} engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} dependencies: - ip: 1.1.8 + ip: 2.0.0 smart-buffer: 4.2.0 /source-list-map/2.0.1: @@ -17412,6 +17726,12 @@ packages: extend-shallow: 3.0.2 dev: true + /split/0.3.3: + resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} + dependencies: + through: 2.3.8 + dev: false + /sprintf-js/1.0.3: resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=} dev: true @@ -17434,6 +17754,13 @@ packages: minipass: 3.1.6 dev: true + /ssri/9.0.1: + resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + minipass: 3.3.4 + dev: true + /stable/0.1.8: resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} dev: true @@ -17514,6 +17841,12 @@ packages: readable-stream: 2.3.7 dev: true + /stream-combiner/0.0.4: + resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} + dependencies: + duplexer: 0.1.2 + dev: false + /stream-each/1.2.3: resolution: {integrity: sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==} dependencies: @@ -17545,7 +17878,7 @@ packages: dev: true /string-width/1.0.2: - resolution: {integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=} + resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} engines: {node: '>=0.10.0'} dependencies: code-point-at: 1.1.0 @@ -17609,7 +17942,7 @@ packages: dev: true /string_decoder/0.10.31: - resolution: {integrity: sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=} + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} dev: false /string_decoder/1.1.1: @@ -17632,7 +17965,7 @@ packages: dev: true /strip-ansi/3.0.1: - resolution: {integrity: sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=} + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} engines: {node: '>=0.10.0'} dependencies: ansi-regex: 2.1.1 @@ -17697,7 +18030,7 @@ packages: dev: true /strip-json-comments/2.0.1: - resolution: {integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo=} + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} /strip-json-comments/3.1.1: @@ -17917,7 +18250,7 @@ packages: dependencies: chownr: 2.0.0 fs-minipass: 2.1.0 - minipass: 3.1.6 + minipass: 3.3.4 minizlib: 2.1.2 mkdirp: 1.0.4 yallist: 4.0.0 @@ -18076,7 +18409,7 @@ packages: dev: true /text-table/0.2.0: - resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true /throttle-debounce/3.0.1: @@ -18084,6 +18417,10 @@ packages: engines: {node: '>=10'} dev: false + /through/2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + /through2/2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} dependencies: @@ -18091,6 +18428,10 @@ packages: xtend: 4.0.2 dev: true + /thunky/1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + dev: false + /timers-browserify/2.0.12: resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} engines: {node: '>=0.6.0'} @@ -18130,7 +18471,7 @@ packages: dev: true /to-fast-properties/2.0.0: - resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} /to-object-path/0.3.0: @@ -18158,7 +18499,6 @@ packages: engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 - dev: true /to-regex/3.0.2: resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} @@ -18217,7 +18557,7 @@ packages: dev: true /traverse/0.3.9: - resolution: {integrity: sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=} + resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} dev: false /traverse/0.6.6: @@ -18248,7 +18588,7 @@ packages: dev: true /truncate-utf8-bytes/1.0.2: - resolution: {integrity: sha1-QFkjkJWS1W94pYGENLC3hInKXys=} + resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} dependencies: utf8-byte-length: 1.0.4 dev: true @@ -18290,12 +18630,22 @@ packages: typescript: 4.7.3 dev: true + /tsutils/3.21.0_typescript@4.7.4: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 4.7.4 + dev: true + /tty-browserify/0.0.0: resolution: {integrity: sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=} dev: true /tunnel-agent/0.6.0: - resolution: {integrity: sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=} + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.2.1 dev: false @@ -18429,7 +18779,7 @@ packages: dev: true /type-check/0.3.2: - resolution: {integrity: sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=} + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.1.2 @@ -18475,6 +18825,12 @@ packages: /type-fest/1.4.0: resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} engines: {node: '>=10'} + dev: true + + /type-fest/2.16.0: + resolution: {integrity: sha512-qpaThT2HQkFb83gMOrdKVsfCN7LKxP26Yq+smPzY1FqoHRjqmjqHXA7n5Gkxi8efirtbeEUxzfEdePthQWCuHw==} + engines: {node: '>=12.20'} + dev: false /type-is/1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} @@ -18490,7 +18846,7 @@ packages: dev: true /typedarray/0.0.6: - resolution: {integrity: sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=} + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} dev: true /typescript/4.7.3: @@ -18499,6 +18855,12 @@ packages: hasBin: true dev: true + /typescript/4.7.4: + resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + /uglify-js/3.15.5: resolution: {integrity: sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==} engines: {node: '>=0.8.0'} @@ -18657,17 +19019,9 @@ packages: /universalify/2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} - dev: true - - /unload/2.2.0: - resolution: {integrity: sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==} - dependencies: - '@babel/runtime': 7.18.3 - detect-node: 2.1.0 - dev: false /unpipe/1.0.0: - resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=} + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} /unset-value/1.0.0: @@ -18774,7 +19128,7 @@ packages: dev: true /url-parse-lax/3.0.0: - resolution: {integrity: sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=} + resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} engines: {node: '>=4'} dependencies: prepend-http: 2.0.0 @@ -18803,17 +19157,25 @@ packages: react: 18.1.0 dev: false + /use-sync-external-store/1.2.0_react@18.1.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.1.0 + dev: false + /use/3.1.1: resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} engines: {node: '>=0.10.0'} dev: true /utf8-byte-length/1.0.4: - resolution: {integrity: sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=} + resolution: {integrity: sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==} dev: true /util-deprecate/1.0.2: - resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} /util.promisify/1.0.0: resolution: {integrity: sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==} @@ -18839,7 +19201,7 @@ packages: dev: true /utils-merge/1.0.1: - resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=} + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} /uuid-browser/3.1.0: @@ -18903,7 +19265,7 @@ packages: dev: false /vary/1.1.2: - resolution: {integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=} + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} /verror/1.10.1: @@ -19001,7 +19363,7 @@ packages: stylus: optional: true dependencies: - esbuild: 0.14.38 + esbuild: 0.14.49 postcss: 8.4.14 resolve: 1.22.0 rollup: 2.72.1 @@ -19045,6 +19407,41 @@ packages: - supports-color dev: true + /vitest/0.12.10_@vitest+ui@0.12.10: + resolution: {integrity: sha512-TVoI6fM7rZ1zIMDjcviY8Dg5XIaPqBwDweaI3oUwvWqUz68cbM49CIHNMkF+UVoSjl94wXiBRdNhsT4ekgWuGA==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@vitest/ui': '*' + c8: '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@vitest/ui': + optional: true + c8: + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.1 + '@types/chai-subset': 1.3.3 + '@vitest/ui': 0.12.10 + chai: 4.3.6 + debug: 4.3.4 + local-pkg: 0.4.1 + tinypool: 0.1.3 + tinyspy: 0.3.2 + vite: 2.9.9 + transitivePeerDependencies: + - less + - sass + - stylus + - supports-color + dev: true + /vm-browserify/1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} dev: true @@ -19122,7 +19519,7 @@ packages: dev: true /wcwidth/1.0.1: - resolution: {integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=} + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: defaults: 1.0.3 dev: true @@ -19131,6 +19528,11 @@ packages: resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==} dev: true + /web-streams-polyfill/3.2.1: + resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} + engines: {node: '>= 8'} + dev: false + /webidl-conversions/3.0.1: resolution: {integrity: sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=} dev: true @@ -19338,7 +19740,7 @@ packages: dev: true /which-module/2.0.0: - resolution: {integrity: sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=} + resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} dev: false /which/1.3.1: @@ -19354,7 +19756,6 @@ packages: hasBin: true dependencies: isexe: 2.0.0 - dev: true /wide-align/1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} @@ -19552,7 +19953,7 @@ packages: strip-ansi: 6.0.1 /wrappy/1.0.2: - resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} /write-file-atomic/3.0.3: resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} @@ -19606,23 +20007,30 @@ packages: engines: {node: '>=12'} dev: true + /xml2js/0.4.23: + resolution: {integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==} + engines: {node: '>=4.0.0'} + dependencies: + sax: 1.2.4 + xmlbuilder: 11.0.1 + dev: false + + /xmlbuilder/11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + dev: false + /xmlbuilder/15.1.1: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} engines: {node: '>=8.0'} dev: true - optional: true - - /xmlbuilder/9.0.7: - resolution: {integrity: sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=} - engines: {node: '>=4.0'} - dev: true /xmlchars/2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} dev: true /xregexp/2.0.0: - resolution: {integrity: sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=} + resolution: {integrity: sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==} dev: false /xtend/4.0.2: @@ -19638,7 +20046,7 @@ packages: engines: {node: '>=10'} /yaku/0.16.7: - resolution: {integrity: sha1-HRlceKqbW/hHnIlblQT9TwhHmE4=} + resolution: {integrity: sha512-Syu3IB3rZvKvYk7yTiyl1bo/jiEFaaStrgv1V2TIJTqYPStSMQVO8EQjg/z+DRzLq/4LIIharNT3iH1hylEIRw==} dev: true /yallist/3.1.1: @@ -19652,6 +20060,11 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} + /yaml/2.1.1: + resolution: {integrity: sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==} + engines: {node: '>= 14'} + dev: false + /yargs-parser/18.1.3: resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} engines: {node: '>=6'} @@ -19712,7 +20125,7 @@ packages: yargs-parser: 21.0.1 /yauzl/2.10.0: - resolution: {integrity: sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=} + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} dependencies: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 @@ -19723,6 +20136,35 @@ packages: engines: {node: '>=10'} dev: true + /youtube-remote/1.0.2: + resolution: {integrity: sha512-IR7OtIuk7NA4wcrRDBbWtLQtM/hcZdtrxgelAwzajvrzzbwGFTf1O+yDzhUWcqOdw2QAp8fKXxS4QQR3e3k24A==} + dependencies: + lodash: 4.17.21 + needle: 2.9.1 + transitivePeerDependencies: + - supports-color + dev: false + /zwitch/1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} dev: true + + /zx/7.0.7: + resolution: {integrity: sha512-cWF5cWqqrTVxgEPmQ8w/LvUXOK3rJTdgC+Tt1nz113+YncNIO0X6UXgCY72UfE8Az/lwOubbEJARXpQ+7RiM9g==} + engines: {node: '>= 16.0.0'} + hasBin: true + dependencies: + '@types/fs-extra': 9.0.13 + '@types/minimist': 1.2.2 + '@types/node': 17.0.36 + '@types/ps-tree': 1.1.2 + '@types/which': 2.0.1 + chalk: 5.0.1 + fs-extra: 10.1.0 + globby: 13.1.2 + minimist: 1.2.6 + node-fetch: 3.2.9 + ps-tree: 1.2.0 + which: 2.0.2 + yaml: 2.1.1 + dev: false diff --git a/turbo.json b/turbo.json index 47cdad4..84c5a30 100644 --- a/turbo.json +++ b/turbo.json @@ -14,7 +14,8 @@ }, "pack": { "dependsOn": ["build"], - "outputs": ["release/**"] + "outputs": ["release/**"], + "cache": false }, "test": { "dependsOn": ["build"],