From 72f0c22e88d31acd0d848f3771c927d75f838f8f Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 24 Jan 2023 22:06:29 +0100 Subject: [PATCH 01/23] add stroke to cuts and cuts are always white --- src/renderer/components/nav-bar/bsmanager-icon.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/components/nav-bar/bsmanager-icon.component.tsx b/src/renderer/components/nav-bar/bsmanager-icon.component.tsx index 60dab613..09a3bc2a 100644 --- a/src/renderer/components/nav-bar/bsmanager-icon.component.tsx +++ b/src/renderer/components/nav-bar/bsmanager-icon.component.tsx @@ -36,7 +36,7 @@ export const BsManagerIcon = memo(({className}: {className?: string}) => { - + From 1cfef9f607c6d21cd13aded515b102336fdd7c49 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 24 Jan 2023 22:55:25 +0100 Subject: [PATCH 02/23] no more verification in available versions list --- src/main/services/bs-installer.service.ts | 36 ++++++++++++------- .../bs-version-item.component.tsx | 12 +++---- .../available-versions-list.components.tsx | 4 +-- .../services/bs-downloader.service.ts | 17 +++++---- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/main/services/bs-installer.service.ts b/src/main/services/bs-installer.service.ts index 8d969a2b..82f828e3 100644 --- a/src/main/services/bs-installer.service.ts +++ b/src/main/services/bs-installer.service.ts @@ -86,6 +86,11 @@ export class BSInstallerService{ if(!(await isOnline({timeout: 1500}))){ throw "no-internet"; } this.utils.createFolderIfNotExist(this.installLocationService.versionsDirectory); + + const dest = this.getPathNotAleardyExist(await this.localVersionService.getVersionPath(bsVersion)); + + const downloadVersion: BSVersion = {...downloadInfos.bsVersion, ...(path.basename(dest) !== downloadInfos.bsVersion.BSVersion && {name: path.basename(dest)})} + this.downloadProcess = spawn( this.getDepotDownloaderExePath(), [ @@ -93,12 +98,14 @@ export class BSInstallerService{ `-depot ${BS_DEPOT}`, `-manifest ${bsVersion.BSManifest}`, `-username ${downloadInfos.username}`, - `-dir \"${this.localVersionService.getVersionFolder(bsVersion)}\"`, + `-dir \"${this.localVersionService.getVersionFolder(downloadVersion)}\"`, (downloadInfos.stay || !downloadInfos.password) && "-remember-password" ], {shell: true, cwd: this.installLocationService.versionsDirectory} ); + this.utils.ipcSend("start-download-version", {success: true, data: downloadVersion}); + return new Promise((resolve, reject) => { this.downloadProcess.stdout.on('data', data => { @@ -160,22 +167,27 @@ export class BSInstallerService{ }) } + private getPathNotAleardyExist(path: string): string{ + let destPath = path; + let folderExist = this.utils.pathExist(destPath); + let i = 0; + + while(folderExist){ + i++; + destPath = `${path} (${i})`; + folderExist = this.utils.pathExist(destPath); + } + + return destPath + } + public async importVersion(path: string): Promise{ const rawBsVersion = await this.localVersionService.getVersionOfBSFolder(path); if(!rawBsVersion){ throw new Error("NOT_BS_FOLDER"); } - const originalPath = await this.localVersionService.getVersionPath(rawBsVersion); - let destPath = originalPath; - let folderExist = this.utils.pathExist(destPath); - let i = 0; - - while(folderExist){ - i++; - destPath = `${originalPath} (${i})`; - folderExist = this.utils.pathExist(destPath); - } + const destPath = this.getPathNotAleardyExist(await this.localVersionService.getVersionPath(rawBsVersion)); await copy(path, destPath, {dereference: true}); @@ -197,7 +209,7 @@ export interface DownloadInfo { export interface DownloadEvent{ type: DownloadEventType, - data?: unknown, + data?: unknown } export type DownloadEventType = "[Password]" | "[Guard]" | "[2FA]" | "[Progress]" | "[Validated]" | "[Finished]" | "[AlreadyDownloading]" | "[Error]" | "[Warning]" | "[SteamID]" | "[Exit]" | "[NoInternet]"; diff --git a/src/renderer/components/nav-bar/nav-bar-items/bs-version-item.component.tsx b/src/renderer/components/nav-bar/nav-bar-items/bs-version-item.component.tsx index 1e8e11bc..3a1c6685 100644 --- a/src/renderer/components/nav-bar/nav-bar-items/bs-version-item.component.tsx +++ b/src/renderer/components/nav-bar/nav-bar-items/bs-version-item.component.tsx @@ -41,13 +41,11 @@ export function BsVersionItem(props: {version: BSVersion}) { ) } - const cancel = () => { - const versionDownload = downloaderService.currentBsVersionDownload$.value; - downloaderService.cancelDownload().then(async res => { - if(!res.success){ return; } - if(!downloaderService.isVerification){ - bsUninstallerService.uninstall(versionDownload).then(res => res && verionManagerService.askInstalledVersions()); - } + const cancel = () => { + const versionDownload = downloaderService.currentBsVersionDownload$.value; + downloaderService.cancelDownload().then(async res => { + if(!res.success){ return; } + bsUninstallerService.uninstall(versionDownload).then(res => res && verionManagerService.askInstalledVersions()); }); } diff --git a/src/renderer/pages/available-versions-list.components.tsx b/src/renderer/pages/available-versions-list.components.tsx index 652f54f9..979952f1 100644 --- a/src/renderer/pages/available-versions-list.components.tsx +++ b/src/renderer/pages/available-versions-list.components.tsx @@ -31,7 +31,7 @@ export function AvailableVersionsList() { const startDownload = () => { setDownloading(() => true) - bsDownloaderService.download(versionSelected, versionManagerService.isVersionInstalled(versionSelected)).finally(() => { + bsDownloaderService.download(versionSelected).finally(() => { setDownloading(() => false); }); } @@ -91,7 +91,7 @@ export function AvailableVersionsList() { { versionSelected && !downloading && ( - + )} diff --git a/src/renderer/services/bs-downloader.service.ts b/src/renderer/services/bs-downloader.service.ts index 28a6ae7f..155c7ce0 100644 --- a/src/renderer/services/bs-downloader.service.ts +++ b/src/renderer/services/bs-downloader.service.ts @@ -25,8 +25,6 @@ export class BsDownloaderService{ private readonly notificationService: NotificationService; private readonly linkOpener: LinkOpenerService; - private _isVerification: boolean = false; - public readonly currentBsVersionDownload$: BehaviorSubject = new BehaviorSubject(null); public readonly downloadProgress$: BehaviorSubject = new BehaviorSubject(0); public readonly selectedBsVersion$: BehaviorSubject = new BehaviorSubject(null); @@ -71,10 +69,15 @@ export class BsDownloaderService{ this.ipcService.sendLazy('bs-download.[2FA]', {args: res.data}); }); + this.ipcService.watch("start-download-version").subscribe(res => { + this.currentBsVersionDownload$.next(res.data); + }); + this.currentBsVersionDownload$.subscribe(version => { if(version){ this.bsVersionManager.setInstalledVersions([...this.bsVersionManager.installedVersions$.value, version]); } else{ this.bsVersionManager.askInstalledVersions(); } }); + } private resetDownload(): void{ @@ -91,7 +94,7 @@ export class BsDownloaderService{ return this.ipcService.send("is-dotnet-6-installed").then(res => res.success && res.data) } - public async download(bsVersion: BSVersion, isVerification?: boolean, isFirstCall = true): Promise>{ + public async download(bsVersion: BSVersion, isFirstCall = true): Promise>{ if(isFirstCall && !this.progressBarService.require()){ return {success: false}; } if(isFirstCall && !(await this.isDotNet6Installed())){ @@ -111,7 +114,6 @@ export class BsDownloaderService{ } this.progressBarService.show(this.downloadProgress$); - this._isVerification = !!isVerification; let promise; if(!this.authService.sessionExist()){ @@ -127,25 +129,22 @@ export class BsDownloaderService{ promise = this.ipcService.send('bs-download.start', {args: {bsVersion, username: this.authService.getSteamUsername()}}); } - this.currentBsVersionDownload$.next(bsVersion); - let res = await promise; if(res.data?.type === "[Password]"){ this.authService.deleteSteamSession(); - res = await this.download(bsVersion, isVerification, false); + res = await this.download(bsVersion, false); } this.progressBarService.hide(true); this.resetDownload(); - if(res.success && isFirstCall){ this.notificationService.notifySuccess({title: `notifications.bs-download.success.titles.${isVerification ? "verification-finished" : "download-success"}`, duration: 3000}); } + if(res.success && isFirstCall){ this.notificationService.notifySuccess({title: "notifications.bs-download.success.titles.download-success", duration: 3000}); } else if(res.data && isFirstCall){ this.notificationService.notifyError({title: `notifications.types.error`, desc: `notifications.bs-download.errors.msg.${res.data}`, duration: 3000}); } return res; } public get isDownloading(): boolean{ return !!this.currentBsVersionDownload$.value; } - public get isVerification(): boolean{ return this._isVerification; } public async getInstallationFolder(): Promise{ const res = await this.ipcService.send("bs-download.installation-folder"); From d889c85b4a31eae048bddd2e583008005542bcfd Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 24 Jan 2023 23:42:12 +0100 Subject: [PATCH 03/23] bumb version --- release/app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/app/package.json b/release/app/package.json index 86686235..4aa31afb 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "bs-manager", - "version": "1.0.0-alpha.7", + "version": "1.0.0-alpha.8", "description": "A foundation for scalable desktop apps", "main": "./dist/main/main.js", "author": { From 5e64ce16f4997c2c5b0fa795a9f194842520177c Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Wed, 25 Jan 2023 00:02:08 +0100 Subject: [PATCH 04/23] add web installer --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 872a396f..5884b8bc 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,8 @@ }, "win": { "target": [ - "nsis" + "nsis", + "nsis-web" ], "icon": "assets/favicon.ico", "certificateSha1": "f3363a89b084f8f6b616babea3c91f9d79e15000" From e82afa7e2264bb7a0cec7f1b63f75c636211d491 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Wed, 25 Jan 2023 20:23:52 +0100 Subject: [PATCH 05/23] disable web installer for auto update --- src/main/services/auto-updater.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/services/auto-updater.service.ts b/src/main/services/auto-updater.service.ts index 21cbdb77..6ffad8e5 100644 --- a/src/main/services/auto-updater.service.ts +++ b/src/main/services/auto-updater.service.ts @@ -16,6 +16,7 @@ export class AutoUpdaterService { constructor(){ autoUpdater.logger = log; autoUpdater.autoDownload = false; + autoUpdater.disableWebInstaller = true this.utilsService = UtilsService.getInstance(); } From 829cace7b9518c7e81b613bc9f633d23878f745e Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Wed, 25 Jan 2023 20:29:08 +0100 Subject: [PATCH 06/23] add selected in glowEffect condition --- .../available-versions/available-version-item.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/components/available-versions/available-version-item.component.tsx b/src/renderer/components/available-versions/available-version-item.component.tsx index 033f4cb8..33d98bbf 100644 --- a/src/renderer/components/available-versions/available-version-item.component.tsx +++ b/src/renderer/components/available-versions/available-version-item.component.tsx @@ -42,7 +42,7 @@ export const AvailableVersionItem = memo(function AvailableVersionItem(props: {v return ( setHovered(true)} onHoverEnd={() => setHovered(false)}> - +
From 8e33214fd067f210b52cebd69eff8e25280da5a8 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Wed, 25 Jan 2023 23:44:38 +0100 Subject: [PATCH 07/23] re-add file verification --- src/main/ipcs/bs-download-ipcs.ts | 10 +--------- src/main/services/bs-installer.service.ts | 7 +++++-- .../nav-bar-items/bs-version-item.component.tsx | 5 ++++- src/renderer/services/bs-downloader.service.ts | 17 +++++++++++------ 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/main/ipcs/bs-download-ipcs.ts b/src/main/ipcs/bs-download-ipcs.ts index 761bfb21..77efef2d 100644 --- a/src/main/ipcs/bs-download-ipcs.ts +++ b/src/main/ipcs/bs-download-ipcs.ts @@ -1,6 +1,5 @@ import { ipcMain } from 'electron'; -import { BSVersion } from 'shared/bs-version.interface'; -import { BSInstallerService, DownloadEventType } from '../services/bs-installer.service'; +import { BSInstallerService, DownloadEventType, DownloadInfo } from '../services/bs-installer.service'; import { IpcRequest } from 'shared/models/ipc'; import { InstallationLocationService } from '../services/installation-location.service'; import { UtilsService } from '../services/utils.service'; @@ -18,13 +17,6 @@ export interface InitDownloadInfoInterface { stay: boolean } -export interface DownloadInfo { - bsVersion: BSVersion, - username: string, - password?: string, - stay?: boolean -} - ipcMain.on('is-dotnet-6-installed', async (event, request: IpcRequest) => { const installer = BSInstallerService.getInstance(); const utils = UtilsService.getInstance(); diff --git a/src/main/services/bs-installer.service.ts b/src/main/services/bs-installer.service.ts index 82f828e3..39ba74e1 100644 --- a/src/main/services/bs-installer.service.ts +++ b/src/main/services/bs-installer.service.ts @@ -87,7 +87,9 @@ export class BSInstallerService{ this.utils.createFolderIfNotExist(this.installLocationService.versionsDirectory); - const dest = this.getPathNotAleardyExist(await this.localVersionService.getVersionPath(bsVersion)); + const versionPath = await this.localVersionService.getVersionPath(bsVersion) + + const dest = !downloadInfos.isVerification ? this.getPathNotAleardyExist(versionPath) : versionPath; const downloadVersion: BSVersion = {...downloadInfos.bsVersion, ...(path.basename(dest) !== downloadInfos.bsVersion.BSVersion && {name: path.basename(dest)})} @@ -204,7 +206,8 @@ export interface DownloadInfo { bsVersion: BSVersion, username: string, password?: string, - stay?: boolean + stay?: boolean, + isVerification: boolean } export interface DownloadEvent{ diff --git a/src/renderer/components/nav-bar/nav-bar-items/bs-version-item.component.tsx b/src/renderer/components/nav-bar/nav-bar-items/bs-version-item.component.tsx index 3a1c6685..04125ce2 100644 --- a/src/renderer/components/nav-bar/nav-bar-items/bs-version-item.component.tsx +++ b/src/renderer/components/nav-bar/nav-bar-items/bs-version-item.component.tsx @@ -43,9 +43,12 @@ export function BsVersionItem(props: {version: BSVersion}) { const cancel = () => { const versionDownload = downloaderService.currentBsVersionDownload$.value; + const wasVerification = downloaderService.isVerification; downloaderService.cancelDownload().then(async res => { if(!res.success){ return; } - bsUninstallerService.uninstall(versionDownload).then(res => res && verionManagerService.askInstalledVersions()); + if(!wasVerification){ + bsUninstallerService.uninstall(versionDownload).then(res => res && verionManagerService.askInstalledVersions()); + } }); } diff --git a/src/renderer/services/bs-downloader.service.ts b/src/renderer/services/bs-downloader.service.ts index 155c7ce0..e1e4843a 100644 --- a/src/renderer/services/bs-downloader.service.ts +++ b/src/renderer/services/bs-downloader.service.ts @@ -1,4 +1,4 @@ -import { DownloadEvent } from 'main/services/bs-installer.service'; +import { DownloadEvent, DownloadInfo } from 'main/services/bs-installer.service'; import { BehaviorSubject } from 'rxjs'; import { distinctUntilChanged, filter, throttleTime } from 'rxjs/operators'; import { IpcResponse } from 'shared/models/ipc'; @@ -25,6 +25,8 @@ export class BsDownloaderService{ private readonly notificationService: NotificationService; private readonly linkOpener: LinkOpenerService; + private _isVerification: boolean = false; + public readonly currentBsVersionDownload$: BehaviorSubject = new BehaviorSubject(null); public readonly downloadProgress$: BehaviorSubject = new BehaviorSubject(0); public readonly selectedBsVersion$: BehaviorSubject = new BehaviorSubject(null); @@ -94,7 +96,7 @@ export class BsDownloaderService{ return this.ipcService.send("is-dotnet-6-installed").then(res => res.success && res.data) } - public async download(bsVersion: BSVersion, isFirstCall = true): Promise>{ + public async download(bsVersion: BSVersion, isVerification?: boolean, isFirstCall = true): Promise>{ if(isFirstCall && !this.progressBarService.require()){ return {success: false}; } if(isFirstCall && !(await this.isDotNet6Installed())){ @@ -114,6 +116,7 @@ export class BsDownloaderService{ } this.progressBarService.show(this.downloadProgress$); + this._isVerification = isVerification; let promise; if(!this.authService.sessionExist()){ @@ -123,22 +126,22 @@ export class BsDownloaderService{ return {success: false}; } this.authService.setSteamSession(res.data.username, res.data.stay); - promise = this.ipcService.send('bs-download.start', {args: {bsVersion, username: res.data.username, password: res.data.password, stay: res.data.stay}}); + promise = this.ipcService.send('bs-download.start', {args: {bsVersion, username: res.data.username, password: res.data.password, stay: res.data.stay, isVerification}}); } else{ - promise = this.ipcService.send('bs-download.start', {args: {bsVersion, username: this.authService.getSteamUsername()}}); + promise = this.ipcService.send('bs-download.start', {args: {bsVersion, username: this.authService.getSteamUsername(), isVerification}}); } let res = await promise; if(res.data?.type === "[Password]"){ this.authService.deleteSteamSession(); - res = await this.download(bsVersion, false); + res = await this.download(bsVersion, isVerification, false); } this.progressBarService.hide(true); this.resetDownload(); - if(res.success && isFirstCall){ this.notificationService.notifySuccess({title: "notifications.bs-download.success.titles.download-success", duration: 3000}); } + if(res.success && isFirstCall){ this.notificationService.notifySuccess({title: `notifications.bs-download.success.titles.${isVerification ? "verification-finished" : "download-success"}`, duration: 3000}); } else if(res.data && isFirstCall){ this.notificationService.notifyError({title: `notifications.types.error`, desc: `notifications.bs-download.errors.msg.${res.data}`, duration: 3000}); } return res; @@ -151,6 +154,8 @@ export class BsDownloaderService{ return res.success ? res.data : ""; } + public get isVerification(): boolean{ return this._isVerification; } + public setInstallationFolder(path: string): Promise>{ return this.ipcService.send("bs-download.set-installation-folder", {args: path}); } From 2b9829d57ab3d7b13bff1d7f9532a44f5b469a5d Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Wed, 25 Jan 2023 23:46:55 +0100 Subject: [PATCH 08/23] bumb version --- release/app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/app/package.json b/release/app/package.json index 4aa31afb..12a0284a 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "bs-manager", - "version": "1.0.0-alpha.8", + "version": "1.0.0", "description": "A foundation for scalable desktop apps", "main": "./dist/main/main.js", "author": { From 571a4f23eab5e4ce044ed074ca8311e54bc26261 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Thu, 26 Jan 2023 00:09:30 +0100 Subject: [PATCH 09/23] re-enable web installer --- src/main/services/auto-updater.service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/services/auto-updater.service.ts b/src/main/services/auto-updater.service.ts index 6ffad8e5..21cbdb77 100644 --- a/src/main/services/auto-updater.service.ts +++ b/src/main/services/auto-updater.service.ts @@ -16,7 +16,6 @@ export class AutoUpdaterService { constructor(){ autoUpdater.logger = log; autoUpdater.autoDownload = false; - autoUpdater.disableWebInstaller = true this.utilsService = UtilsService.getInstance(); } From 36521a2b1b04f1057927383a764f4f35690a54ca Mon Sep 17 00:00:00 2001 From: 0xAuthenticity <121343169+0xAuthenticity@users.noreply.github.com> Date: Sat, 28 Jan 2023 02:23:42 -0500 Subject: [PATCH 10/23] Update default-configuration.config.ts --- src/renderer/config/default-configuration.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/config/default-configuration.config.ts b/src/renderer/config/default-configuration.config.ts index 5aac4dfb..e34f69eb 100644 --- a/src/renderer/config/default-configuration.config.ts +++ b/src/renderer/config/default-configuration.config.ts @@ -4,9 +4,9 @@ export const defaultConfiguration: {[key in DefaultConfigKey]: any} = { "theme": "os", "language": window.navigator.language.length <= 2 ? `${window.navigator.language}-${window.navigator.language.toLocaleUpperCase()}` : window.navigator.language, "supported_languages": ["en-US", "en-EN", "fr-FR", "es-ES"], - "default_mods": ["SongCore", "ScoreSaber", "BeatSaverDownloader", "BeatSaverVoting", "PlaylistManager", "ModelDownloader"] + "default_mods": ["SongCore", "WhyIsThereNoLeaderboard", "BeatSaverDownloader", "BeatSaverVoting", "PlaylistManager", "ModelDownloader"] } export type DefaultConfigKey = "first-color" | "second-color" | "theme" | "language" | "supported_languages" | "default_mods"; -export type ThemeConfig = "dark" | "light" | "os" \ No newline at end of file +export type ThemeConfig = "dark" | "light" | "os" From 5592242963befdbf84e4aaafcb77220eaa847132 Mon Sep 17 00:00:00 2001 From: Synaelle Date: Thu, 2 Feb 2023 15:12:47 +0100 Subject: [PATCH 11/23] Correction d'orthographe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit J'ai corrigé la majorité des fautes que j'ai pu trouvé, ainsi que les problèmes de cohérence dans la mention du jeu. C'est à dire que des fois le jeu est appelé BeatSaber et des fois Beat Saber. --- assets/jsons/translations/fr.json | 78 +++++++++++++++---------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index 1730df61..a49483d6 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -84,7 +84,7 @@ } }, "available-versions": { - "title": "Choisi une version", + "title": "Choisis une version", "steam-release": "Notes de version", "dropdown": { "refresh": "Rafraichir la liste", @@ -99,7 +99,7 @@ }, "appearance": { "title": "Apparence", - "description": "Choisi les deux couleurs principales de BSManager.", + "description": "Choisis les deux couleurs principales de BSManager.", "reset": "Réinitialiser", "sub-title": "Thème", "themes": { @@ -115,7 +115,7 @@ }, "additional-content": { "title": "Contenus additionnels", - "description": "Les contenus additionnels te permet de personaliser BeatSaber !", + "description": "Les contenus additionnels te permettent de personaliser Beat Saber!", "deep-links": { "sub-title": "Installations OneClick" } @@ -138,7 +138,7 @@ }, "patreon": { "title": "Soutenir BSManager 💖", - "description": "Soutien le projet et aide-nous à fournir des améliorations continues à BSManager.", + "description": "Soutiens le projet et aide-nous à fournir des améliorations continues à BSManager.", "buttons": { "support": "Soutenir BSManager 🥰", "supporters": "Supporteurs 👀" @@ -170,7 +170,7 @@ }, "common": { "msg": { - "error-occurred": "Une erreur c'est produite" + "error-occurred": "Une erreur s'est produite" } }, "shared": { @@ -180,8 +180,8 @@ "no-internet": "Pas d'internet" }, "msg": { - "operation-running": "Attend la fin de l'opération en cours puis recommences.", - "no-internet": "Verifie t'a connexion internet et recommence." + "operation-running": "Attends la fin de l'opération en cours puis recommence.", + "no-internet": "Verifie ta connexion internet et recommence." } } }, @@ -194,11 +194,11 @@ }, "warnings": { "msg": { - "ManifestChecksum": "Le manifest télécharger précédemment ne correspond pas au nouveau 🤔", + "ManifestChecksum": "Le manifest téléchargé précédemment ne correspond pas au nouveau 🤔", "ConnectionTimeout": "Ta connexion internet semble instable 🥶", - "ConnectionLost": "La connexion a été perdue, retentative...", - "ConnectionError": "Impossible de se connecter à Steam, retentative...", - "Unknown": "Quelque chose d'étrange c'est produit 🤔 Votre connexion est surement instable." + "ConnectionLost": "La connexion a été perdue, nouvelle tentative...", + "ConnectionError": "Impossible de se connecter à Steam, nouvelle tentative...", + "Unknown": "Quelque chose d'étrange s'est produit 🤔 Votre connexion est surement instable." } }, "errors": { @@ -206,31 +206,31 @@ "dotnet-required": ".NET 6 Requis" }, "msg": { - "401": "Steam semble pas vouloir nous laisser télécharger BeatSaber 😢", + "401": "Steam ne semble pas vouloir nous laisser télécharger Beat Saber 😢", "404": "Impossible de contacter les serveurs de Steam.", "Password": "Le mot de passe est invalide.", "InvalidCredentials": "Ton e-mail ou mot de passe est invalide 😴", "InvalidPassword": "Ton mot de passe est invalide 😕", "NoManifest": "Aucun manifest n'a été trouvé.", "DirectoryCreate": "Impossible d'installer les dossiers nécessaires.", - "NotAvailableApp": "Tu essayes de télécharger BeatSaber alors que tu ne l'as pas ? 🤣", - "DepotNotFound": "Impossible de télécharger BeatSaber 😥 réessaye plus tard 😕", + "NotAvailableApp": "Tu essayes de télécharger Beat Saber alors que tu ne l'as pas ? 🤣", + "DepotNotFound": "Impossible de télécharger Beat Saber 😥 réessaye plus tard 😕", "NotCompleted": "Le téléchargement n'a pas pu se terminer ¯\\_(ツ)_/¯", - "InvalidManifest": "Impossible de télécharger BeatSaber 😥 réessaye plus tard 😕", - "NoValidKey": "Impossible de télécharger BeatSaber 😥 réessaye plus tard 😕", - "NoManifestCode": "Impossible de télécharger BeatSaber 😥 réessaye plus tard 😕", - "Unknown": "Une erreur inconnue c'est produite ¯\\_(ツ)_/¯", + "InvalidManifest": "Impossible de télécharger Beat Saber 😥 réessaye plus tard 😕", + "NoValidKey": "Impossible de télécharger Beat Saber 😥 réessaye plus tard 😕", + "NoManifestCode": "Impossible de télécharger Beat Saber 😥 réessaye plus tard 😕", + "Unknown": "Une erreur inconnue s'est produite ¯\\_(ツ)_/¯", "NoServer": "Impossible de contacter les serveurs de Steam.", - "NotAllowed": "Apparemment tu n'es pas autorisé à télécharger BeatSaber 🥱", + "NotAllowed": "Apparemment tu n'es pas autorisé à télécharger Beat Saber 🥱", "ConnectionTimeout": "Impossible de se connecter à Steam 😕", - "SteamLib": "Si tu à cette erreur, report le bug sur GitHub avec les logs stp.", + "SteamLib": "Si tu as cette erreur, signale le bug sur GitHub avec les logs stp.", "ConnectionError": "Impossible de se connecter à Steam après 10 essais 🤯", "LicenceError": "Impossible d'obtenir la liste des licences.", "verification-failed": "La vérification a échoué, réessaye plus tard.", - "RateLimitExceeded": "Tu as essayé trop de fois attend un peu et recommence plus tard.", + "RateLimitExceeded": "Tu as essayé trop de fois attends un peu et recommence plus tard.", "AlreadyDownloading": "Un téléchargement est déjà en cours", "no-internet": "Pas de connexion internet.", - "dotnet-required": ".NET 6 Runtime doit être installé pour pouvoir télécharger une version de BeatSaber. Télécharge-le en cliquant sur le bouton ci-dessous." + "dotnet-required": ".NET 6 Runtime doit être installé pour pouvoir télécharger une version de Beat Saber. Télécharge-le en cliquant sur le bouton ci-dessous." }, "actions":{ "download-dotnet": "Télécharger .NET 6" @@ -249,7 +249,7 @@ }, "errors":{ "import-error":{ - "desc": "Vérifier que le dossier sélectionné est une installation de BeatSaber." + "desc": "Vérifier que le dossier sélectionné est une installation de Beat Saber." } } }, @@ -316,14 +316,14 @@ "UNABLE_TO_LAUNCH": "Lancement impossible", "STEAM_NOT_RUNNING": "Steam n'est pas lancé", "OCULUS_NOT_RUNNING": "Oculus n'est pas lancé", - "BS_ALREADY_RUNNING": "BeatSaber est déjà lancé", + "BS_ALREADY_RUNNING": "Beat Saber est déjà lancé", "EXE_NOT_FINDED": "Fichiers manquants", "EXIT": "Arrêt brutal" }, "msg": { - "STEAM_NOT_RUNNING": "Steam doit être en cours d'exécution pour lancer BeatSaber.", - "OCULUS_NOT_RUNNING": "Oculus doit être en cours d'exécution pour lancer BeatSaber.", - "BS_ALREADY_RUNNING": "Ferme BeatSaber avant de le lancer à nouveau.", + "STEAM_NOT_RUNNING": "Steam doit être en cours d'exécution pour lancer Beat Saber.", + "OCULUS_NOT_RUNNING": "Oculus doit être en cours d'exécution pour lancer Beat Saber.", + "BS_ALREADY_RUNNING": "Ferme Beat Saber avant de le lancer à nouveau.", "EXE_NOT_FINDED": "Quelques fichiers semblent manquants. Essaye de vérifier les fichiers.", "EXIT": "BeatSaber s'est arrêté brusquement, essaye de vérifier les fichiers." }, @@ -347,12 +347,12 @@ "CantClone": "Clonage impossible" }, "msg": { - "CantEditSteam": "Tu ne peut pas éditer la version Steam. Tu peut la cloner par contre." + "CantEditSteam": "Tu ne peux pas éditer la version Steam. Tu peux la cloner par contre." } }, "success": { "titles": { - "CloningFinished": "Clonage terminer 🎉" + "CloningFinished": "Clonage terminé 🎉" } } }, @@ -363,10 +363,10 @@ "warning": "Mods installés 🤔" }, "msg": { - "success": "Tous les mods on été installés.", + "success": "Tous les mods ont été installés.", "warning": "Un ou plusieurs mods n'ont pas pu être installés.", "errors": { - "no-mods": "Aucun mods à installer.", + "no-mods": "Aucun mod à installer.", "cannot-install-bsipa": "L'installation de BSIPA à échoué 😨" } } @@ -386,7 +386,7 @@ "success": "Mods désintallés 🎉" }, "msg": { - "success": "Tous les mods on été désintallés.", + "success": "Tous les mods ont été désintallés.", "errors": { "no-mods": "Aucun mod n'est installé dans dans cette version 😑" } @@ -456,14 +456,14 @@ }, "bs-uninstall": { "title": "Désinstaller", - "description": "Est-tu sûr de vouloir désinstaller BeatSaber {version} ? Tu vas devoir la retélécharger pour y jouer.", + "description": "Es-tu sûr de vouloir désinstaller Beat Saber {version} ? Tu vas devoir la retélécharger pour y jouer.", "buttons": { "submit": "Désinstaller" } }, "install-folder": { "title": "Dossier d'installation", - "description": "Changer le dossier d'installation par défaut, va engendrer le déplacement de toutes les données installer vers le nouveau dossier.", + "description": "Changer le dossier d'installation par défaut, cela va engendrer le déplacement de toutes les données installer vers le nouveau dossier.", "buttons": { "submit": "Choisir un dossier" } @@ -506,12 +506,12 @@ "multiple": "Supprimer les maps ?" }, "desc": { - "single": "Est-tu sur de vouloir supprimer la map {name} ?", - "multiple": "Est-tu sur de vouloir supprimer les {nb} maps ?" + "single": "Es-tu sur de vouloir supprimer la map {name} ?", + "multiple": "Es-tu sur de vouloir supprimer les {nb} maps ?" }, "info": { "desc": { - "single": "Cette map fait partie des maps paratagées", + "single": "Cette map fait partie des maps partagées", "multiple": "Ces maps font parties des maps partagées" }, "title": { @@ -552,7 +552,7 @@ "li-1": "Vous pouvez rencontrer des problèmes qui n'existent pas dans le jeu de base. 99.9% des bugs, plantages et ralentissements sont dus aux mods.", "li-2": "Les mods sont susceptibles de ne plus fonctionner à cause des mises à jour et c'est normal - soyez patient et respectueux lorsque cela se produit, parce que les moddeurs sont bénévoles et ont une vie.", "li-3": "Beat Games ne cherche pas volontairement à casser les mods. Ils souhaitent améliorer la base du jeu et parfois cela casse les mods, mais ce n'est pas dans leur objectif de tuer les mods.", - "p-2": "N'attaquez pas les développeurs pour des problèmes relatifs aux mods, et inversement - les moddeurs et les développeurs sont deux groupes distincts. Ne sois pas idiot, d'accord ?" + "p-2": "N'attaquez pas les développeurs pour des problèmes relatifs aux mods, et inversement - les moddeurs et les développeurs sont deux groupes distincts. Ne soyez pas idiots, d'accord ?" } }, "maps": { @@ -694,4 +694,4 @@ "PM" ] } -} \ No newline at end of file +} From a4fd92a01477de2f32d901738f907f09cded98e6 Mon Sep 17 00:00:00 2001 From: MathieuG-P Date: Mon, 6 Feb 2023 21:14:40 +0100 Subject: [PATCH 12/23] remove ModelDownload from default mods --- src/renderer/config/default-configuration.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/config/default-configuration.config.ts b/src/renderer/config/default-configuration.config.ts index e34f69eb..a6a9eed9 100644 --- a/src/renderer/config/default-configuration.config.ts +++ b/src/renderer/config/default-configuration.config.ts @@ -4,7 +4,7 @@ export const defaultConfiguration: {[key in DefaultConfigKey]: any} = { "theme": "os", "language": window.navigator.language.length <= 2 ? `${window.navigator.language}-${window.navigator.language.toLocaleUpperCase()}` : window.navigator.language, "supported_languages": ["en-US", "en-EN", "fr-FR", "es-ES"], - "default_mods": ["SongCore", "WhyIsThereNoLeaderboard", "BeatSaverDownloader", "BeatSaverVoting", "PlaylistManager", "ModelDownloader"] + "default_mods": ["SongCore", "WhyIsThereNoLeaderboard", "BeatSaverDownloader", "BeatSaverVoting", "PlaylistManager"] } export type DefaultConfigKey = "first-color" | "second-color" | "theme" | "language" | "supported_languages" | "default_mods"; From 211a3b9a3945037ad6cb85ce4f7337207c801bca Mon Sep 17 00:00:00 2001 From: MathieuG-P Date: Mon, 6 Feb 2023 21:37:17 +0100 Subject: [PATCH 13/23] disable support button + fix button hightlight even if disabled + fix click exec even if disabled --- src/renderer/components/shared/bsm-button.component.tsx | 8 +++++--- src/renderer/pages/settings-page.component.tsx | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/renderer/components/shared/bsm-button.component.tsx b/src/renderer/components/shared/bsm-button.component.tsx index 4671a62f..fb95f172 100644 --- a/src/renderer/components/shared/bsm-button.component.tsx +++ b/src/renderer/components/shared/bsm-button.component.tsx @@ -1,5 +1,5 @@ import { BsmIcon, BsmIconType } from "../svgs/bsm-icon.component" -import { useRef, CSSProperties } from "react"; +import { useRef, CSSProperties, MouseEvent } from "react"; import { BsmImage } from "./bsm-image.component"; import { useTranslation } from "renderer/hooks/use-translation.hook"; import { useClickOutside } from "renderer/hooks/use-click-outside.hook"; @@ -45,15 +45,17 @@ export function BsmButton({className, style, imgClassName, iconClassName, icon, const renderTypeColor = (() => { if(typeColor === "primary"){ return ""; } - if(!typeColor){ return `bg-light-main-color-2 dark:bg-main-color-2 ${!withBar && "hover:brightness-125"}`; } + if(!typeColor){ return `bg-light-main-color-2 dark:bg-main-color-2 ${(!withBar && !disabled) && "hover:brightness-125"}`; } if(typeColor === "cancel"){ return "bg-gray-500"; } if(typeColor === "error"){ return "bg-red-500"; } if(typeColor === "success"){ return "bg-green-500"; } return ""; })(); + const handleClick = (e: MouseEvent) => !disabled && onClick(e); + return ( -
+
{ image && } { icon && } {text && (type === "submit" ? : {t(text)})} diff --git a/src/renderer/pages/settings-page.component.tsx b/src/renderer/pages/settings-page.component.tsx index d20c5adb..f99d6183 100644 --- a/src/renderer/pages/settings-page.component.tsx +++ b/src/renderer/pages/settings-page.component.tsx @@ -293,7 +293,7 @@ export function SettingsPage() {
- +
From 61a879044882614bff8e5250150134b3df199460 Mon Sep 17 00:00:00 2001 From: MathieuG-P Date: Mon, 6 Feb 2023 22:03:34 +0100 Subject: [PATCH 14/23] bumb version --- release/app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/app/package.json b/release/app/package.json index 12a0284a..1ba06a43 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "bs-manager", - "version": "1.0.0", + "version": "1.0.1", "description": "A foundation for scalable desktop apps", "main": "./dist/main/main.js", "author": { From 26203548887fcfbf064f336c44e0ccbde62c35d6 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Wed, 15 Feb 2023 00:50:49 +0100 Subject: [PATCH 15/23] init virtual scroll maps list --- package-lock.json | 540 +++++-- package.json | 4 + release/app/package-lock.json | 1238 ++++++++++++++++- .../local-maps-list-panel.component.tsx | 101 +- .../map-item.component.tsx | 2 +- .../maps-row.component.tsx | 69 + 6 files changed, 1728 insertions(+), 226 deletions(-) create mode 100644 src/renderer/components/maps-mangement-components/maps-row.component.tsx diff --git a/package-lock.json b/package-lock.json index ee6b0ed1..69d89f18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,8 @@ "dependencies": { "@node-steam/vdf": "^2.2.0", "@tippyjs/react": "^4.2.6", + "@types/react-virtualized-auto-sizer": "^1.0.1", + "@types/react-window": "^1.8.5", "archiver": "^5.3.1", "dateformat": "^5.0.3", "dot-prop": "^7.2.0", @@ -30,6 +32,8 @@ "react-dom": "^18.2.0", "react-range": "^1.8.14", "react-router-dom": "^6.3.0", + "react-virtualized-auto-sizer": "^1.0.7", + "react-window": "^1.8.8", "regedit": "^5.1.1", "rfdc": "^1.3.0", "rxjs": "^7.5.6", @@ -734,7 +738,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "devOptional": true, + "dev": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -746,7 +750,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "devOptional": true, + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1843,7 +1847,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6.0.0" } @@ -1871,7 +1875,7 @@ "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "devOptional": true + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.17", @@ -2016,6 +2020,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2028,6 +2033,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, "engines": { "node": ">= 8" } @@ -2036,6 +2042,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2464,25 +2471,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "devOptional": true + "dev": true }, "node_modules/@types/archiver": { "version": "5.3.1", @@ -2787,7 +2794,7 @@ "version": "17.0.23", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "devOptional": true + "dev": true }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -2815,8 +2822,7 @@ "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/qs": { "version": "6.9.7", @@ -2834,7 +2840,6 @@ "version": "17.0.52", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.52.tgz", "integrity": "sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -2868,6 +2873,22 @@ "@types/react": "^17" } }, + "node_modules/@types/react-virtualized-auto-sizer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz", + "integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-window": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz", + "integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -2890,8 +2911,7 @@ "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "node_modules/@types/semver": { "version": "7.3.13", @@ -3541,7 +3561,7 @@ "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "devOptional": true, + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -3593,6 +3613,7 @@ "version": "1.8.2", "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, "dependencies": { "acorn": "^7.0.0", "acorn-walk": "^7.0.0", @@ -3603,6 +3624,7 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -3614,6 +3636,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, "engines": { "node": ">=0.4.0" } @@ -3772,6 +3795,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3896,7 +3920,8 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true }, "node_modules/argparse": { "version": "2.0.1", @@ -4334,6 +4359,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, "engines": { "node": ">=8" } @@ -4461,6 +4487,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -4794,6 +4821,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, "engines": { "node": ">= 6" } @@ -4855,6 +4883,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, "funding": [ { "type": "individual", @@ -5127,7 +5156,8 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/color-string": { "version": "1.9.1", @@ -5528,7 +5558,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "devOptional": true + "dev": true }, "node_modules/cross-env": { "version": "7.0.3", @@ -5789,6 +5819,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -5911,8 +5942,7 @@ "node_modules/csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", - "dev": true + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -6138,6 +6168,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6218,6 +6249,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dev": true, "dependencies": { "acorn-node": "^1.8.2", "defined": "^1.0.0", @@ -6233,13 +6265,14 @@ "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.3.1" } @@ -6307,7 +6340,8 @@ "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true }, "node_modules/dmg-builder": { "version": "23.6.0", @@ -8751,6 +8785,7 @@ "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -8787,6 +8822,7 @@ "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -8909,6 +8945,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -9137,6 +9174,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -9149,7 +9187,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/function.prototype.name": { "version": "1.1.5", @@ -9297,6 +9336,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -9491,6 +9531,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -9902,6 +9943,45 @@ "node": "^8.11.2 || >=10" } }, + "node_modules/iconv-corefoundation/node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "optional": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/iconv-corefoundation/node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "optional": true + }, + "node_modules/iconv-corefoundation/node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -10167,6 +10247,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -10232,6 +10313,7 @@ "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, "dependencies": { "has": "^1.0.3" }, @@ -10273,6 +10355,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -10299,6 +10382,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -10357,6 +10441,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "engines": { "node": ">=0.12.0" } @@ -12406,6 +12491,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "dev": true, "engines": { "node": ">=10" } @@ -12793,7 +12879,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "devOptional": true + "dev": true }, "node_modules/make-fetch-happen": { "version": "10.2.1", @@ -12904,6 +12990,11 @@ "node": ">= 4.0.0" } }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, "node_modules/memory-fs": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", @@ -12926,6 +13017,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "engines": { "node": ">= 8" } @@ -12943,6 +13035,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -13080,6 +13173,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -13229,6 +13323,7 @@ "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -13527,6 +13622,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, "engines": { "node": ">= 6" } @@ -14002,7 +14098,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-to-regexp": { "version": "0.1.7", @@ -14028,12 +14125,14 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -14158,6 +14257,7 @@ "version": "8.4.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -14276,6 +14376,7 @@ "version": "14.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dev": true, "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -14292,6 +14393,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "dev": true, "dependencies": { "camelcase-css": "^2.0.1" }, @@ -14310,6 +14412,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" @@ -14717,6 +14820,7 @@ "version": "6.0.10", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -14759,7 +14863,8 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -15317,6 +15422,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, "funding": [ { "type": "github", @@ -15517,10 +15623,39 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/react-virtualized-auto-sizer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.7.tgz", + "integrity": "sha512-Mxi6lwOmjwIjC1X4gABXMJcKHsOo0xWl3E3ugOgufB8GJU+MqrtY35aBuvCYv/razQ1Vbp7h1gWJjGjoNN5pmA==", + "engines": { + "node": ">8.0.0" + }, + "peerDependencies": { + "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc", + "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc" + } + }, + "node_modules/react-window": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.8.tgz", + "integrity": "sha512-D4IiBeRtGXziZ1n0XklnFGu7h9gU684zepqyKzgPNzrsrk7xOCxni+TCckjg2Nr/DiaEEGVVmnhYSlT2rB47dQ==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "memoize-one": ">=3.1.1 <6" + }, + "engines": { + "node": ">8.0.0" + }, + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, "dependencies": { "pify": "^2.3.0" } @@ -15529,6 +15664,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -15593,6 +15729,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -15746,6 +15883,7 @@ "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, "dependencies": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -15830,6 +15968,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -15889,6 +16028,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "funding": [ { "type": "github", @@ -16560,6 +16700,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -16913,6 +17054,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -16977,6 +17119,7 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", + "dev": true, "dependencies": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -17025,6 +17168,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -17036,6 +17180,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -17293,6 +17438,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -17488,7 +17634,7 @@ "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "devOptional": true, + "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -17531,7 +17677,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.4.0" } @@ -17540,7 +17686,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "devOptional": true + "dev": true }, "node_modules/tsconfig-paths": { "version": "3.14.1", @@ -17668,7 +17814,7 @@ "version": "4.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", - "devOptional": true, + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -17926,7 +18072,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "devOptional": true + "dev": true }, "node_modules/v8-to-istanbul": { "version": "8.1.1", @@ -18674,6 +18820,7 @@ "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, "engines": { "node": ">= 6" } @@ -18719,7 +18866,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6" } @@ -19221,7 +19368,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "devOptional": true, + "dev": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -19230,7 +19377,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "devOptional": true, + "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -20145,7 +20292,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "devOptional": true + "dev": true }, "@jridgewell/set-array": { "version": "1.1.2", @@ -20167,7 +20314,7 @@ "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "devOptional": true + "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.17", @@ -20292,6 +20439,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -20300,12 +20448,14 @@ "@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true }, "@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -20606,25 +20756,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "devOptional": true + "dev": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true + "dev": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true + "dev": true }, "@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "devOptional": true + "dev": true }, "@types/archiver": { "version": "5.3.1", @@ -20933,7 +21083,7 @@ "version": "17.0.23", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "devOptional": true + "dev": true }, "@types/parse-json": { "version": "4.0.0", @@ -20961,8 +21111,7 @@ "@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "@types/qs": { "version": "6.9.7", @@ -20980,7 +21129,6 @@ "version": "17.0.52", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.52.tgz", "integrity": "sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A==", - "dev": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -21014,6 +21162,22 @@ "@types/react": "^17" } }, + "@types/react-virtualized-auto-sizer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz", + "integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==", + "requires": { + "@types/react": "*" + } + }, + "@types/react-window": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz", + "integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==", + "requires": { + "@types/react": "*" + } + }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -21038,8 +21202,7 @@ "@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "@types/semver": { "version": "7.3.13", @@ -21476,8 +21639,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "dev": true, - "requires": {} + "dev": true }, "@webpack-cli/info": { "version": "1.5.0", @@ -21492,8 +21654,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", - "dev": true, - "requires": {} + "dev": true }, "@xtuc/ieee754": { "version": "1.2.0", @@ -21539,7 +21700,7 @@ "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "devOptional": true + "dev": true }, "acorn-globals": { "version": "6.0.0", @@ -21563,20 +21724,19 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "requires": {} + "dev": true }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-node": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, "requires": { "acorn": "^7.0.0", "acorn-walk": "^7.0.0", @@ -21586,14 +21746,16 @@ "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true } } }, "acorn-walk": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true }, "address": { "version": "1.2.1", @@ -21653,8 +21815,7 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} + "dev": true }, "ansi-escapes": { "version": "4.3.2", @@ -21698,6 +21859,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -21809,7 +21971,8 @@ "arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true }, "argparse": { "version": "2.0.1", @@ -22133,7 +22296,8 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true }, "bl": { "version": "4.1.0", @@ -22250,6 +22414,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -22276,8 +22441,7 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/browserslist-config-erb/-/browserslist-config-erb-0.0.3.tgz", "integrity": "sha512-y47DryCY92lxkKyRVMlaZvXAolIY7U33q9e4CS0MdWeJkoAht7OzsrkfdZFCBOP3H5q1EVUxS0L7VVsKM6gZCQ==", - "dev": true, - "requires": {} + "dev": true }, "bs-logger": { "version": "0.2.6", @@ -22504,7 +22668,8 @@ "camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true }, "caniuse-api": { "version": "3.0.0", @@ -22544,6 +22709,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -22736,7 +22902,8 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "color-string": { "version": "1.9.1", @@ -23045,7 +23212,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "devOptional": true + "dev": true }, "cross-env": { "version": "7.0.3", @@ -23077,8 +23244,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", - "dev": true, - "requires": {} + "dev": true }, "css-loader": { "version": "6.7.2", @@ -23212,7 +23378,8 @@ "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true }, "cssnano": { "version": "5.1.14", @@ -23266,8 +23433,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true, - "requires": {} + "dev": true }, "csso": { "version": "4.2.0", @@ -23304,8 +23470,7 @@ "csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", - "dev": true + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "damerau-levenshtein": { "version": "1.0.8", @@ -23468,7 +23633,8 @@ "defined": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==" + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "dev": true }, "delayed-stream": { "version": "1.0.0", @@ -23526,6 +23692,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dev": true, "requires": { "acorn-node": "^1.8.2", "defined": "^1.0.0", @@ -23535,13 +23702,14 @@ "didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "devOptional": true + "dev": true }, "diff-sequences": { "version": "27.5.1", @@ -23593,7 +23761,8 @@ "dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true }, "dmg-builder": { "version": "23.6.0", @@ -24520,8 +24689,7 @@ "version": "13.0.1", "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-13.0.1.tgz", "integrity": "sha512-n7fGBDNV3xSKbWDUES2FfsNAJhuqADcwzshX6ci6qoszUnH6p4dzrLnSFqYkw5Sn7M+aarp2BTf7JDOK88M+bg==", - "dev": true, - "requires": {} + "dev": true }, "eslint-config-erb": { "version": "4.0.3", @@ -24689,8 +24857,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "requires": {} + "dev": true }, "eslint-visitor-keys": { "version": "2.1.0", @@ -24747,8 +24914,7 @@ "version": "8.5.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "requires": {} + "dev": true }, "eslint-import-resolver-node": { "version": "0.3.6", @@ -25047,8 +25213,7 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", - "dev": true, - "requires": {} + "dev": true }, "eslint-plugin-react": { "version": "7.31.11", @@ -25111,8 +25276,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "dev": true, - "requires": {} + "dev": true }, "eslint-scope": { "version": "5.1.1", @@ -25403,6 +25567,7 @@ "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -25433,6 +25598,7 @@ "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, "requires": { "reusify": "^1.0.4" } @@ -25525,6 +25691,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -25700,12 +25867,14 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "optional": true }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "function.prototype.name": { "version": "1.1.5", @@ -25811,6 +25980,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -25959,6 +26129,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -26271,6 +26442,38 @@ "requires": { "cli-truncate": "^2.1.0", "node-addon-api": "^1.6.3" + }, + "dependencies": { + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "optional": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "optional": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } } }, "iconv-lite": { @@ -26286,8 +26489,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "requires": {} + "dev": true }, "identity-obj-proxy": { "version": "3.0.0", @@ -26464,6 +26666,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -26511,6 +26714,7 @@ "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, "requires": { "has": "^1.0.3" } @@ -26533,7 +26737,8 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -26551,6 +26756,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -26590,7 +26796,8 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-number-object": { "version": "1.0.7", @@ -27531,8 +27738,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "27.5.1", @@ -28269,7 +28475,8 @@ "lilconfig": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==" + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "dev": true }, "lines-and-columns": { "version": "1.2.4", @@ -28563,7 +28770,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "devOptional": true + "dev": true }, "make-fetch-happen": { "version": "10.2.1", @@ -28651,6 +28858,11 @@ "fs-monkey": "^1.0.3" } }, + "memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, "memory-fs": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", @@ -28672,7 +28884,8 @@ "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true }, "methods": { "version": "1.1.2", @@ -28684,6 +28897,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -28775,7 +28989,8 @@ "minimist": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true }, "minipass": { "version": "3.3.4", @@ -28880,7 +29095,8 @@ "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true }, "natural-compare": { "version": "1.4.0", @@ -29092,7 +29308,8 @@ "object-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true }, "object-inspect": { "version": "1.12.2", @@ -29431,7 +29648,8 @@ "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "path-to-regexp": { "version": "0.1.7", @@ -29454,12 +29672,14 @@ "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true }, "pidtree": { "version": "0.5.0", @@ -29547,6 +29767,7 @@ "version": "8.4.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "dev": true, "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -29589,34 +29810,31 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "dev": true, - "requires": {} + "dev": true }, "postcss-discard-duplicates": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true, - "requires": {} + "dev": true }, "postcss-discard-empty": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true, - "requires": {} + "dev": true }, "postcss-discard-overridden": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true, - "requires": {} + "dev": true }, "postcss-import": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dev": true, "requires": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -29627,6 +29845,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "dev": true, "requires": { "camelcase-css": "^2.0.1" } @@ -29635,6 +29854,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, "requires": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" @@ -29717,8 +29937,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, - "requires": {} + "dev": true }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -29762,8 +29981,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true, - "requires": {} + "dev": true }, "postcss-normalize-display-values": { "version": "5.1.0", @@ -29872,6 +30090,7 @@ "version": "6.0.10", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, "requires": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -29899,7 +30118,8 @@ "postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, "prelude-ls": { "version": "1.2.1", @@ -30331,7 +30551,8 @@ "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true }, "quick-lru": { "version": "5.1.1", @@ -30387,8 +30608,7 @@ "react-colorful": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", - "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", - "requires": {} + "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==" }, "react-dom": { "version": "18.2.0", @@ -30408,8 +30628,7 @@ "react-range": { "version": "1.8.14", "resolved": "https://registry.npmjs.org/react-range/-/react-range-1.8.14.tgz", - "integrity": "sha512-v2nyD5106rHf9dwHzq+WRlhCes83h1wJRHIMFjbZsYYsO6LF4mG/mR3cH7Cf+dkeHq65DItuqIbLn/3jjYjsHg==", - "requires": {} + "integrity": "sha512-v2nyD5106rHf9dwHzq+WRlhCes83h1wJRHIMFjbZsYYsO6LF4mG/mR3cH7Cf+dkeHq65DItuqIbLn/3jjYjsHg==" }, "react-refresh": { "version": "0.12.0", @@ -30421,8 +30640,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/react-refresh-typescript/-/react-refresh-typescript-2.0.7.tgz", "integrity": "sha512-KbuW57FauO11e6a9gU836sCm3M3z0b2+J2qPhUudg0QplOfz0eAF3gMeshcUC/ChfNLJCK1SZxvYmUtRxiZE5A==", - "dev": true, - "requires": {} + "dev": true }, "react-router": { "version": "6.4.3", @@ -30470,10 +30688,25 @@ } } }, + "react-virtualized-auto-sizer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.7.tgz", + "integrity": "sha512-Mxi6lwOmjwIjC1X4gABXMJcKHsOo0xWl3E3ugOgufB8GJU+MqrtY35aBuvCYv/razQ1Vbp7h1gWJjGjoNN5pmA==" + }, + "react-window": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.8.tgz", + "integrity": "sha512-D4IiBeRtGXziZ1n0XklnFGu7h9gU684zepqyKzgPNzrsrk7xOCxni+TCckjg2Nr/DiaEEGVVmnhYSlT2rB47dQ==", + "requires": { + "@babel/runtime": "^7.0.0", + "memoize-one": ">=3.1.1 <6" + } + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, "requires": { "pify": "^2.3.0" }, @@ -30481,7 +30714,8 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true } } }, @@ -30538,6 +30772,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -30663,6 +30898,7 @@ "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, "requires": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -30722,7 +30958,8 @@ "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true }, "rfdc": { "version": "1.3.0", @@ -30769,6 +31006,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "requires": { "queue-microtask": "^1.2.2" } @@ -31282,7 +31520,8 @@ "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true }, "source-map-support": { "version": "0.5.21", @@ -31510,8 +31749,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", - "dev": true, - "requires": {} + "dev": true }, "stylehacks": { "version": "5.1.1", @@ -31554,7 +31792,8 @@ "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true }, "svgo": { "version": "2.8.0", @@ -31589,8 +31828,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/tailwind-scrollbar/-/tailwind-scrollbar-2.0.1.tgz", "integrity": "sha512-OcR7qHBbux4k+k6bWqnEQFYFooLK/F4dhkBz6nvswIoaA9ancZ5h20e0tyV7ifSWLDCUBtpG+1NHRA8HMRH/wg==", - "dev": true, - "requires": {} + "dev": true }, "tailwind-scrollbar-hide": { "version": "1.1.7", @@ -31601,6 +31839,7 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", + "dev": true, "requires": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -31631,6 +31870,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, "requires": { "is-glob": "^4.0.3" } @@ -31639,6 +31879,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "dev": true, "requires": { "postcss-selector-parser": "^6.0.10" } @@ -31648,8 +31889,7 @@ "tailwindcss-scoped-groups": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/tailwindcss-scoped-groups/-/tailwindcss-scoped-groups-2.0.0.tgz", - "integrity": "sha512-uE9PJzfjqzsKlZ0dUjG5yPwBmkEZ/qmrXMLjykRs0otolUHAIclbtV49JQGyeYLo8YA7WPMgzKOg2e4snVyHqw==", - "requires": {} + "integrity": "sha512-uE9PJzfjqzsKlZ0dUjG5yPwBmkEZ/qmrXMLjykRs0otolUHAIclbtV49JQGyeYLo8YA7WPMgzKOg2e4snVyHqw==" }, "tapable": { "version": "2.2.1", @@ -31842,6 +32082,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -31977,7 +32218,7 @@ "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "devOptional": true, + "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -31998,13 +32239,13 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "devOptional": true + "dev": true }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "devOptional": true + "dev": true } } }, @@ -32111,7 +32352,7 @@ "version": "4.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", - "devOptional": true + "dev": true }, "unbox-primitive": { "version": "1.0.2", @@ -32246,14 +32487,12 @@ "use-delayed-state": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-delayed-state/-/use-delayed-state-1.2.0.tgz", - "integrity": "sha512-i/7nyyHZsJ+2qGwbb9XGTViBDs43j/57pxdbhbyhTD6XNTzqCvaZQSfIa/SLAGR7eFPK9+UV62Dfzia/aYdwPw==", - "requires": {} + "integrity": "sha512-i/7nyyHZsJ+2qGwbb9XGTViBDs43j/57pxdbhbyhTD6XNTzqCvaZQSfIa/SLAGR7eFPK9+UV62Dfzia/aYdwPw==" }, "use-double-click": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/use-double-click/-/use-double-click-1.0.5.tgz", - "integrity": "sha512-71LUca6NtzpzHYlcfM/dOdmwvmvpMbzeIVQpN87w+DctpLiMCXtZpsN8FNWPgHpPBtNhvucPUHIDh5al8D8C7w==", - "requires": {} + "integrity": "sha512-71LUca6NtzpzHYlcfM/dOdmwvmvpMbzeIVQpN87w+DctpLiMCXtZpsN8FNWPgHpPBtNhvucPUHIDh5al8D8C7w==" }, "use-fit-text": { "version": "2.4.0", @@ -32289,7 +32528,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "devOptional": true + "dev": true }, "v8-to-istanbul": { "version": "8.1.1", @@ -32610,8 +32849,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "dev": true, - "requires": {} + "dev": true } } }, @@ -32786,8 +33024,7 @@ "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "requires": {} + "dev": true }, "xml-name-validator": { "version": "3.0.0", @@ -32832,7 +33069,8 @@ "yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true }, "yargs": { "version": "17.6.2", @@ -32869,7 +33107,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "devOptional": true + "dev": true }, "yocto-queue": { "version": "0.1.0", diff --git a/package.json b/package.json index 5884b8bc..714e5408 100644 --- a/package.json +++ b/package.json @@ -226,6 +226,8 @@ "dependencies": { "@node-steam/vdf": "^2.2.0", "@tippyjs/react": "^4.2.6", + "@types/react-virtualized-auto-sizer": "^1.0.1", + "@types/react-window": "^1.8.5", "archiver": "^5.3.1", "dateformat": "^5.0.3", "dot-prop": "^7.2.0", @@ -246,6 +248,8 @@ "react-dom": "^18.2.0", "react-range": "^1.8.14", "react-router-dom": "^6.3.0", + "react-virtualized-auto-sizer": "^1.0.7", + "react-window": "^1.8.8", "regedit": "^5.1.1", "rfdc": "^1.3.0", "rxjs": "^7.5.6", diff --git a/release/app/package-lock.json b/release/app/package-lock.json index 305cf6b6..53a556d1 100644 --- a/release/app/package-lock.json +++ b/release/app/package-lock.json @@ -1,8 +1,1226 @@ { "name": "bs-manager", - "version": "0.2.0", - "lockfileVersion": 1, + "version": "1.0.1", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "bs-manager", + "version": "1.0.1", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "ctrlc-windows": "^2.0.0" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-commands": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/command-line-commands/-/command-line-commands-3.0.2.tgz", + "integrity": "sha512-ac6PdCtdR6q7S3HN+JiVLIWGHY30PRYIEl2qPo+FuEuzwAUk0UYyimrngrg7FvF/mCr4Jgoqv5ZnHZgads50rw==", + "dependencies": { + "array-back": "^4.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-commands/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "dependencies": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/command-line-usage/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/command-line-usage/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, + "node_modules/ctrlc-windows": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ctrlc-windows/-/ctrlc-windows-2.0.0.tgz", + "integrity": "sha512-bpZLqGGwJ/2uLIXmhBYC4TObQlpfEeCCzmJ1At6TWFIWcY4FydkJLTolABFPUxmDYHeC9y95wdYBLa4U4PSktA==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.5", + "neon-cli": "^0.8.1" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-config": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/git-config/-/git-config-0.0.7.tgz", + "integrity": "sha512-LidZlYZXWzVjS+M3TEwhtYBaYwLeOZrXci1tBgqp/vDdZTBMl02atvwb6G35L64ibscYoPnxfbwwUS+VZAISLA==", + "dependencies": { + "iniparser": "~1.0.5" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/iniparser": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/iniparser/-/iniparser-1.0.5.tgz", + "integrity": "sha512-i40MWqgTU6h/70NtMsDVVDLjDYWwcIR1yIEVDPfxZIJno9z9L4s83p/V7vAu2i48Vj0gpByrkGFub7ko9XvPrw==", + "engines": { + "node": "*" + } + }, + "node_modules/inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-promises-safe": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/make-promises-safe/-/make-promises-safe-5.1.0.tgz", + "integrity": "sha512-AfdZ49rtyhQR/6cqVKGoH7y4ql7XkS5HJI1lZm0/5N6CQosy1eYbBJ/qbhkKHzo17UH7M918Bysf6XB9f3kS1g==" + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/minipass": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", + "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/neon-cli": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/neon-cli/-/neon-cli-0.8.3.tgz", + "integrity": "sha512-I44MB8PD0AEyFr/b5icR4sX1tsjdkb2T2uWEStG4Uf5C/jzalZPn7eazbQrW6KDyXNd8bc+LVuOr1v6CGTa1KQ==", + "dependencies": { + "chalk": "^4.1.0", + "command-line-args": "^5.1.1", + "command-line-commands": "^3.0.1", + "command-line-usage": "^6.1.0", + "git-config": "0.0.7", + "handlebars": "^4.7.6", + "inquirer": "^7.3.3", + "make-promises-safe": "^5.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "toml": "^3.0.0", + "ts-typed-json": "^0.3.2", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^3.0.0" + }, + "bin": { + "neon": "bin/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dependencies": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-typed-json": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ts-typed-json/-/ts-typed-json-0.3.2.tgz", + "integrity": "sha512-Tdu3BWzaer7R5RvBIJcg9r8HrTZgpJmsX+1meXMJzYypbkj8NK2oJN0yvm4Dp/Iv6tzFa/L5jKRmEVTga6K3nA==" + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/uglify-js": { + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.2.tgz", + "integrity": "sha512-AaQNokTNgExWrkEYA24BTNMSjyqEXPSfhqoS0AxmHkCJ4U+Dyy5AvbGV/sqxuxficEfGGoX3zWw9R7QpLFfEsg==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", + "dependencies": { + "builtins": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, + "node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + }, "dependencies": { "@mapbox/node-pre-gyp": { "version": "1.0.9", @@ -724,6 +1942,14 @@ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==" }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -734,14 +1960,6 @@ "strip-ansi": "^6.0.1" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", diff --git a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx index 493b03df..c8fba402 100644 --- a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx @@ -12,6 +12,10 @@ import BeatConflict from "../../../../assets/images/apngs/beat-conflict.png" import { BsmButton } from "../shared/bsm-button.component" import { useTranslation } from "renderer/hooks/use-translation.hook" import BeatWaitingImg from "../../../../assets/images/apngs/beat-waiting.png" +import { VariableSizeList } from "react-window" +import AutoSizer from "react-virtualized-auto-sizer" +import { MapsRow } from "./maps-row.component" +import { motion } from "framer-motion" type Props = { version: BSVersion, @@ -30,6 +34,7 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc const [maps, setMaps] = useState(null); const [subs] = useState([]); const [selectedMaps, setSelectedMaps] = useState([]); + const [itemPerRow, setItemPerRow] = useState(2); const t = useTranslation(); useImperativeHandle(forwardRef ,()=>({ @@ -66,28 +71,7 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc mapsManager.deleteMaps([map], version).then(res => res && loadMaps()) }, [version]); - const extractMapDiffs = (map: BsmLocalMap): Map => { - const res = new Map(); - if(map.bsaverInfo?.versions[0]?.diffs){ - map.bsaverInfo.versions[0].diffs.forEach(diff => { - const arr = res.get(diff.characteristic) || []; - const diffName = map.rawInfo._difficultyBeatmapSets.find(set => set._beatmapCharacteristicName === diff.characteristic)._difficultyBeatmaps.find(rawDiff => rawDiff._difficulty === diff.difficulty)?._customData?._difficultyLabel || diff.difficulty - arr.push({name: diffName, type: diff.difficulty, stars: diff.stars}); - res.set(diff.characteristic, arr); - }); - return res; - } - - map.rawInfo._difficultyBeatmapSets.forEach(set => { - set._difficultyBeatmaps.forEach(diff => { - const arr = res.get(set._beatmapCharacteristicName) || []; - arr.push({name: diff._customData?._difficultyLabel || diff._difficulty, type: diff._difficulty, stars: null}); - res.set(set._beatmapCharacteristicName, arr); - }); - }); - - return res; - } + const onMapSelected = useCallback((map: BsmLocalMap) => { const maps = [...selectedMaps]; @@ -216,53 +200,42 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc } - const renderMaps = (): JSX.Element[] => { - return maps.reduce((acc, current) => { - if(isMapFitFilter(current)){ - acc.push(renderMapItem(current)); - } - return acc - }, []); - } - const renderMapItem = (map: BsmLocalMap) => { - - return _map.hash === map.hash)} - diffs={extractMapDiffs(map)} mapId={map.bsaverInfo?.id} ranked={map.bsaverInfo?.ranked} autorId={map.bsaverInfo?.uploader?.id} likes={map.bsaverInfo?.stats?.upvotes} createdAt={map.bsaverInfo?.createdAt} - onDelete={handleDelete} - onSelected={onMapSelected} - callBackParam={map} - />; + const preppedMaps: BsmLocalMap[][] = (() => { + + if(!maps){ return []; } + + //const mapsPerRow = //Math.floor(listWidth / 400); + const res: BsmLocalMap[][] = []; + let mapsRow: BsmLocalMap[] = [] + + for(const [i, map] of maps.entries()){ + if(!isMapFitFilter(map)){ continue; } + if(mapsRow.length === itemPerRow){ + res.push(mapsRow); + mapsRow = []; + } + mapsRow.push(map); + } + + console.log(res, "11"); + + return res; + })(); + + const updateItemPerRow = (listWidth: number) => { + const newPerRow = Math.floor(listWidth / 400); + if(newPerRow === itemPerRow){ return; } + console.log("AA"); + setItemPerRow(newPerRow); } return (
-
    - {maps?.length ? renderMaps() : ( - maps === null ? ( -
    -  - {t("modals.download-maps.loading-maps")} -
    - ) : ( -
    - - {t("pages.version-viewer.maps.tabs.maps.empty-maps.text")} - {e.preventDefault(); mapsDownloader.openDownloadMapModal(version)}}/> -
    - ) - )} -
+ 100} itemCount={preppedMaps.length} itemData={preppedMaps}> + {(props) => } + +
) }) diff --git a/src/renderer/components/maps-mangement-components/map-item.component.tsx b/src/renderer/components/maps-mangement-components/map-item.component.tsx index e915a278..0951a3c8 100644 --- a/src/renderer/components/maps-mangement-components/map-item.component.tsx +++ b/src/renderer/components/maps-mangement-components/map-item.component.tsx @@ -148,7 +148,7 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl, } return ( - setHovered(true)} onHoverEnd={() => setHovered(false)} style={{zIndex: hovered && 5, transform: "translateZ(0) scale(1.0, 1.0)", backfaceVisibility: "hidden"}}> + setHovered(true)} onHoverEnd={() => setHovered(false)} style={{zIndex: hovered && 5, transform: "translateZ(0) scale(1.0, 1.0)", backfaceVisibility: "hidden"}}> {(diffsPanelHovered || bottomBarHovered) && ( diff --git a/src/renderer/components/maps-mangement-components/maps-row.component.tsx b/src/renderer/components/maps-mangement-components/maps-row.component.tsx new file mode 100644 index 00000000..f46a584b --- /dev/null +++ b/src/renderer/components/maps-mangement-components/maps-row.component.tsx @@ -0,0 +1,69 @@ +import { CSSProperties } from "react" +import { BsvMapCharacteristic } from "shared/models/maps/beat-saver.model" +import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface" +import { ParsedMapDiff, MapItem } from "./map-item.component" + +type Props = { + maps: BsmLocalMap[], + style?: CSSProperties +} + +export function MapsRow({maps, style}: Props) { + + const handleDelete = () => { + + } + + const onMapSelected = () => { + + } + + const extractMapDiffs = (map: BsmLocalMap): Map => { + const res = new Map(); + if(map.bsaverInfo?.versions[0]?.diffs){ + map.bsaverInfo.versions[0].diffs.forEach(diff => { + const arr = res.get(diff.characteristic) || []; + const diffName = map.rawInfo._difficultyBeatmapSets.find(set => set._beatmapCharacteristicName === diff.characteristic)._difficultyBeatmaps.find(rawDiff => rawDiff._difficulty === diff.difficulty)?._customData?._difficultyLabel || diff.difficulty + arr.push({name: diffName, type: diff.difficulty, stars: diff.stars}); + res.set(diff.characteristic, arr); + }); + return res; + } + + map.rawInfo._difficultyBeatmapSets.forEach(set => { + set._difficultyBeatmaps.forEach(diff => { + const arr = res.get(set._beatmapCharacteristicName) || []; + arr.push({name: diff._customData?._difficultyLabel || diff._difficulty, type: diff._difficulty, stars: null}); + res.set(set._beatmapCharacteristicName, arr); + }); + }); + + return res; + } + + const renderMapItem = (map: BsmLocalMap) => { + + return ; + } + + return ( +
    + {maps && maps.map(renderMapItem)} +
+ ) +} From a7e81cfa8a92bc4afdffecd8f41c93b73eec6291 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Thu, 16 Feb 2023 00:30:23 +0100 Subject: [PATCH 16/23] virtual scroll maps list resize work --- .../local-maps-list-panel.component.tsx | 61 ++++++++++++------- .../map-item.component.tsx | 2 +- .../maps-row.component.tsx | 2 +- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx index c8fba402..c138d105 100644 --- a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx @@ -3,19 +3,14 @@ import { BSVersion } from "shared/bs-version.interface" import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react" import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface" import { Subscription } from "rxjs" -import { MapItem, ParsedMapDiff } from "./map-item.component" -import { BsvMapCharacteristic, MapFilter } from "shared/models/maps/beat-saver.model" +import { MapFilter } from "shared/models/maps/beat-saver.model" import { useInView } from "framer-motion" import { MapsDownloaderService } from "renderer/services/maps-downloader.service" -import { BsmImage } from "../shared/bsm-image.component" -import BeatConflict from "../../../../assets/images/apngs/beat-conflict.png" -import { BsmButton } from "../shared/bsm-button.component" import { useTranslation } from "renderer/hooks/use-translation.hook" -import BeatWaitingImg from "../../../../assets/images/apngs/beat-waiting.png" import { VariableSizeList } from "react-window" -import AutoSizer from "react-virtualized-auto-sizer" import { MapsRow } from "./maps-row.component" -import { motion } from "framer-motion" +import { BehaviorSubject } from "rxjs" +import { debounceTime } from "rxjs/operators" type Props = { version: BSVersion, @@ -35,6 +30,7 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc const [subs] = useState([]); const [selectedMaps, setSelectedMaps] = useState([]); const [itemPerRow, setItemPerRow] = useState(2); + const [listHeight, setListHeight] = useState(0); const t = useTranslation(); useImperativeHandle(forwardRef ,()=>({ @@ -63,6 +59,34 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc } }, [isVisible, version]); + useEffect(() => { + + if(!isVisible){ return () => {}; } + + const updateItemPerRow = (listWidth: number) => { + const newPerRow = Math.min(Math.floor(listWidth / 400), 3); + if(newPerRow === itemPerRow){ return; } + setItemPerRow(newPerRow); + }; + + const heightObserver$ = new BehaviorSubject(0); + + const observer = new ResizeObserver(() => { + updateItemPerRow(ref.current?.clientWidth || 0); + heightObserver$.next(ref.current?.clientHeight || 0) + }); + + observer.observe(ref.current); + + const sub = heightObserver$.pipe(debounceTime(100)).subscribe(setListHeight); + + return () => { + observer.disconnect(); + sub.unsubscribe(); + } + + }, [isVisible, itemPerRow]) + const loadMaps = () => { subs.push(mapsManager.getMaps(version).subscribe(localMaps => setMaps(() => [...localMaps]))); } @@ -205,11 +229,10 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc if(!maps){ return []; } - //const mapsPerRow = //Math.floor(listWidth / 400); const res: BsmLocalMap[][] = []; let mapsRow: BsmLocalMap[] = [] - for(const [i, map] of maps.entries()){ + for(const map of maps){ if(!isMapFitFilter(map)){ continue; } if(mapsRow.length === itemPerRow){ res.push(mapsRow); @@ -218,24 +241,18 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc mapsRow.push(map); } - console.log(res, "11"); + if(mapsRow.length){ + res.push(mapsRow); + } return res; })(); - const updateItemPerRow = (listWidth: number) => { - const newPerRow = Math.floor(listWidth / 400); - if(newPerRow === itemPerRow){ return; } - console.log("AA"); - setItemPerRow(newPerRow); - } - return (
- 100} itemCount={preppedMaps.length} itemData={preppedMaps}> - {(props) => } - - + 108} itemCount={preppedMaps.length} itemData={preppedMaps} layout="vertical" style={{scrollbarGutter: "stable both-edges"}}> + {(props) => } +
) }) diff --git a/src/renderer/components/maps-mangement-components/map-item.component.tsx b/src/renderer/components/maps-mangement-components/map-item.component.tsx index 0951a3c8..d02ce687 100644 --- a/src/renderer/components/maps-mangement-components/map-item.component.tsx +++ b/src/renderer/components/maps-mangement-components/map-item.component.tsx @@ -148,7 +148,7 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl, } return ( - setHovered(true)} onHoverEnd={() => setHovered(false)} style={{zIndex: hovered && 5, transform: "translateZ(0) scale(1.0, 1.0)", backfaceVisibility: "hidden"}}> + setHovered(true)} onHoverEnd={() => setHovered(false)} style={{zIndex: hovered && 5, transform: "translateZ(0) scale(1.0, 1.0)", backfaceVisibility: "hidden"}}> {(diffsPanelHovered || bottomBarHovered) && ( diff --git a/src/renderer/components/maps-mangement-components/maps-row.component.tsx b/src/renderer/components/maps-mangement-components/maps-row.component.tsx index f46a584b..c92933a0 100644 --- a/src/renderer/components/maps-mangement-components/maps-row.component.tsx +++ b/src/renderer/components/maps-mangement-components/maps-row.component.tsx @@ -62,7 +62,7 @@ export function MapsRow({maps, style}: Props) { } return ( -
    +
      {maps && maps.map(renderMapItem)}
    ) From 64280509b08821a66e650dd97a7ea9be2e6954c6 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Fri, 17 Feb 2023 01:26:16 +0100 Subject: [PATCH 17/23] huge maps deletion and export speed improvement + optimize map component update rate --- src/main/ipcs/bs-maps-ipcs.ts | 4 +- .../local-maps-manager.service.ts | 35 +++---------- .../local-maps-list-panel.component.tsx | 49 +++++++++++-------- .../map-item.component.tsx | 6 +-- .../maps-row.component.tsx | 32 ++++++------ src/renderer/services/maps-manager.service.ts | 2 +- .../models/maps/bsm-local-map.interface.ts | 1 + 7 files changed, 58 insertions(+), 71 deletions(-) diff --git a/src/main/ipcs/bs-maps-ipcs.ts b/src/main/ipcs/bs-maps-ipcs.ts index 4868df52..88f9733e 100644 --- a/src/main/ipcs/bs-maps-ipcs.ts +++ b/src/main/ipcs/bs-maps-ipcs.ts @@ -50,11 +50,11 @@ ipcMain.on("unlink-version-maps", async (event, request: IpcRequest<{version: BS }); -ipcMain.on("delete-maps", async (event, request: IpcRequest<{version: BSVersion, maps: BsmLocalMap[]}>) => { +ipcMain.on("delete-maps", async (event, request: IpcRequest<{maps: BsmLocalMap[]}>) => { const utils = UtilsService.getInstance(); const maps = LocalMapsManagerService.getInstance(); - maps.deleteMaps(request.args.maps, request.args.version).then(() => { + maps.deleteMaps(request.args.maps).then(() => { utils.ipcSend(request.responceChannel, {success: true}); }).catch(err => { utils.ipcSend(request.responceChannel, {success: false, error: err}); diff --git a/src/main/services/additional-content/local-maps-manager.service.ts b/src/main/services/additional-content/local-maps-manager.service.ts index 12580c40..5b31ef11 100644 --- a/src/main/services/additional-content/local-maps-manager.service.ts +++ b/src/main/services/additional-content/local-maps-manager.service.ts @@ -100,7 +100,7 @@ export class LocalMapsManagerService { const hash = await this.computeMapHash(mapPath, rawInfoString); - return {rawInfo, coverUrl, songUrl, hash}; + return {rawInfo, coverUrl, songUrl, hash, path: mapPath}; } private async downloadMapZip(zipUrl: string): Promise<{zip: StreamZip.StreamZipAsync, zipPath: string}>{ @@ -115,28 +115,6 @@ export class LocalMapsManagerService { return {zip, zipPath}; } - private async getAbsoluteFolderOfMaps(maps: BsmLocalMap[], version: BSVersion): Promise{ - - const mapsFolder = await this.getMapsFolderPath(version); - - const res: string[] = []; - const mapHashs = maps.map(map => map.hash); - - const mapsFolders = readdirSync(mapsFolder, {withFileTypes: true}); - - for(const content of mapsFolders){ - if(!content.isDirectory()){ continue; } - const mapFolderPath = path.join(mapsFolder, content.name); - const { hash } = await this.loadMapInfoFromPath(mapFolderPath); - if(mapHashs.includes(hash)){ - res.push(mapFolderPath); - } - } - - return res; - - } - private openOneClickDownloadMapWindow(mapId: string, isHash = false): void{ ipcMain.once("one-click-map-info", async (event, req: IpcRequest) => { @@ -201,16 +179,15 @@ export class LocalMapsManagerService { } - public async deleteMaps(maps: BsmLocalMap[], verion?: BSVersion){ + public async deleteMaps(maps: BsmLocalMap[]){ - const mapsFolders = await this.getAbsoluteFolderOfMaps(maps, verion); + const mapsFolders = maps.map(map => map.path); const mapsHashsToDelete = maps.map(map => map.hash); for(const folder of mapsFolders){ const { hash } = await this.loadMapInfoFromPath(folder); - if(mapsHashsToDelete.includes(hash)){ - await this.utils.deleteFolder(folder); - } + if(!mapsHashsToDelete.includes(hash)){ continue; } + await this.utils.deleteFolder(folder); } } @@ -257,7 +234,7 @@ export class LocalMapsManagerService { } else{ - const mapsFolders = await this.getAbsoluteFolderOfMaps(maps, version); + const mapsFolders = maps.map(map => map.path); for(const folder of mapsFolders){ archive.directory(folder, path.basename(folder)); diff --git a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx index c138d105..6ab4ea1c 100644 --- a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx @@ -6,7 +6,6 @@ import { Subscription } from "rxjs" import { MapFilter } from "shared/models/maps/beat-saver.model" import { useInView } from "framer-motion" import { MapsDownloaderService } from "renderer/services/maps-downloader.service" -import { useTranslation } from "renderer/hooks/use-translation.hook" import { VariableSizeList } from "react-window" import { MapsRow } from "./maps-row.component" import { BehaviorSubject } from "rxjs" @@ -28,20 +27,19 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc const isVisible = useInView(ref, {once: true}); const [maps, setMaps] = useState(null); const [subs] = useState([]); - const [selectedMaps, setSelectedMaps] = useState([]); + const [selectedMaps$] = useState>(new BehaviorSubject([])); const [itemPerRow, setItemPerRow] = useState(2); const [listHeight, setListHeight] = useState(0); - const t = useTranslation(); useImperativeHandle(forwardRef ,()=>({ deleteMaps(){ - const mapsToDelete = selectedMaps.length === 0 ? maps : selectedMaps - mapsManager.deleteMaps(mapsToDelete, version).finally(loadMaps); + const mapsToDelete = selectedMaps$.value.length === 0 ? maps : selectedMaps$.value + mapsManager.deleteMaps(mapsToDelete, version).then(res => res && removeMapsFromList(mapsToDelete)); }, exportMaps(){ - mapsManager.exportMaps(version, selectedMaps) + mapsManager.exportMaps(version, selectedMaps$.value) } - }), [selectedMaps, maps, version]); + }), [selectedMaps$.value, maps, version]); useEffect(() => { @@ -91,23 +89,34 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc subs.push(mapsManager.getMaps(version).subscribe(localMaps => setMaps(() => [...localMaps]))); } - const handleDelete = useCallback((map: BsmLocalMap) => { - mapsManager.deleteMaps([map], version).then(res => res && loadMaps()) - }, [version]); + const removeMapsFromList = (mapsToRemove: BsmLocalMap[]) => { + const filtredMaps = maps.filter(map => !mapsToRemove.some(toDeleteMaps => map.hash === toDeleteMaps.hash)); + setMaps(() => filtredMaps); + }; - + const handleDelete = useCallback((map: BsmLocalMap) => { + mapsManager.deleteMaps([map], version).then(res => res && removeMapsFromList([map])); + }, [version, maps]); const onMapSelected = useCallback((map: BsmLocalMap) => { - const maps = [...selectedMaps]; - if(maps.some(selectedMap => selectedMap.hash === map.hash)){ - const i = maps.findIndex(selectedMap => selectedMap.hash === map.hash); - maps.splice(i, 1); + + console.log(map); + + const mapsCopy = [...selectedMaps$.value]; + if(mapsCopy.some(selectedMap => selectedMap.hash === map.hash)){ + const i = mapsCopy.findIndex(selectedMap => selectedMap.hash === map.hash); + mapsCopy.splice(i, 1); } else{ - maps.push(map); + mapsCopy.push(map); } - setSelectedMaps(() => maps); - }, [selectedMaps]); + + console.log(mapsCopy); + + selectedMaps$.next(mapsCopy); + }, [selectedMaps$.value]); + + console.log(selectedMaps$.value); const isMapFitFilter = (map: BsmLocalMap): boolean => { @@ -250,8 +259,8 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc return (
    - 108} itemCount={preppedMaps.length} itemData={preppedMaps} layout="vertical" style={{scrollbarGutter: "stable both-edges"}}> - {(props) => } + 108} itemCount={preppedMaps.length} itemData={preppedMaps} layout="vertical" style={{scrollbarGutter: "stable both-edges"}} itemKey={(i, data) => data[i].map(map => map.hash).join()}> + {(props) => }
    ) diff --git a/src/renderer/components/maps-mangement-components/map-item.component.tsx b/src/renderer/components/maps-mangement-components/map-item.component.tsx index d02ce687..345d088f 100644 --- a/src/renderer/components/maps-mangement-components/map-item.component.tsx +++ b/src/renderer/components/maps-mangement-components/map-item.component.tsx @@ -236,8 +236,4 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl,
) -}, areEqual) - -function areEqual(prevProps: MapItemProps, nextProps: MapItemProps): boolean { - return equal(prevProps, nextProps); -} +}, equal); diff --git a/src/renderer/components/maps-mangement-components/maps-row.component.tsx b/src/renderer/components/maps-mangement-components/maps-row.component.tsx index c92933a0..30ba64fe 100644 --- a/src/renderer/components/maps-mangement-components/maps-row.component.tsx +++ b/src/renderer/components/maps-mangement-components/maps-row.component.tsx @@ -1,22 +1,26 @@ -import { CSSProperties } from "react" +import { CSSProperties, memo } from "react" +import { useObservable } from "renderer/hooks/use-observable.hook" +import { distinctUntilChanged, map } from "rxjs/operators" +import { BehaviorSubject } from "rxjs" import { BsvMapCharacteristic } from "shared/models/maps/beat-saver.model" import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface" import { ParsedMapDiff, MapItem } from "./map-item.component" +import equal from "fast-deep-equal/es6" type Props = { maps: BsmLocalMap[], - style?: CSSProperties + style?: CSSProperties, + onMapDelete: (map: BsmLocalMap) => void, + onMapSelect: (map: BsmLocalMap) => void, + selectedMaps$: BehaviorSubject } -export function MapsRow({maps, style}: Props) { +export const MapsRow = memo(({maps, style, selectedMaps$, onMapSelect, onMapDelete}: Props) => { - const handleDelete = () => { - - } - - const onMapSelected = () => { - - } + const selectedMaps = useObservable(selectedMaps$.pipe( + map(selectedMaps => selectedMaps.filter(selected => maps.some(map => map.hash === selected.hash))), + distinctUntilChanged(equal) + ), []); const extractMapDiffs = (map: BsmLocalMap): Map => { const res = new Map(); @@ -53,10 +57,10 @@ export function MapsRow({maps, style}: Props) { songAutor={map.rawInfo._songAuthorName} bpm={map.rawInfo._beatsPerMinute} duration={map.bsaverInfo?.metadata?.duration} - selected={false} + selected={selectedMaps.some(selected => selected.hash === map.hash)} diffs={extractMapDiffs(map)} mapId={map.bsaverInfo?.id} ranked={map.bsaverInfo?.ranked} autorId={map.bsaverInfo?.uploader?.id} likes={map.bsaverInfo?.stats?.upvotes} createdAt={map.bsaverInfo?.createdAt} - onDelete={handleDelete} - onSelected={onMapSelected} + onDelete={onMapDelete} + onSelected={onMapSelect} callBackParam={map} />; } @@ -66,4 +70,4 @@ export function MapsRow({maps, style}: Props) { {maps && maps.map(renderMapItem)} ) -} +}, equal); diff --git a/src/renderer/services/maps-manager.service.ts b/src/renderer/services/maps-manager.service.ts index a801fa83..49382ebd 100644 --- a/src/renderer/services/maps-manager.service.ts +++ b/src/renderer/services/maps-manager.service.ts @@ -133,7 +133,7 @@ export class MapsManagerService { this.progressBar.showFake(.008); } - const res = await this.ipcService.send("delete-maps", {args: {version, maps}}); + const res = await this.ipcService.send("delete-maps", {args: {maps}}); if(showProgressBar){ this.progressBar.hide(true); diff --git a/src/shared/models/maps/bsm-local-map.interface.ts b/src/shared/models/maps/bsm-local-map.interface.ts index 4c7e5558..2c353465 100644 --- a/src/shared/models/maps/bsm-local-map.interface.ts +++ b/src/shared/models/maps/bsm-local-map.interface.ts @@ -7,4 +7,5 @@ export interface BsmLocalMap { songUrl: string, rawInfo: RawMapInfoData, bsaverInfo?: BsvMapDetail + path: string } \ No newline at end of file From c88d93b0abdd99569934e02d377e9c5651b3f398 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 21 Feb 2023 00:33:33 +0100 Subject: [PATCH 18/23] maps optimisation finished + new ipc system + maps progress bars now accurate --- package-lock.json | 43 ++++++++- package.json | 2 + src/main/ipcs/bs-maps-ipcs.ts | 61 ++++-------- src/main/models/archive.class.ts | 78 +++++++++++++++ src/main/preload.ts | 12 ++- .../local-maps-manager.service.ts | 96 ++++++++++++------- .../local-playlists-manager.service.ts | 2 +- src/main/services/bs-installer.service.ts | 2 +- src/main/services/ipc.service.ts | 65 +++++++++++++ .../beat-saver/beat-saver.service.ts | 5 +- src/main/services/window-manager.service.ts | 6 +- .../local-maps-list-panel.component.tsx | 96 ++++++++++++++++--- .../maps-playlists-panel.component.tsx | 2 +- .../download-maps-modal.component.tsx | 25 +++-- .../text-progress-bar.component.tsx | 20 ++++ .../components/shared/bsm-image.component.tsx | 2 +- src/renderer/preload.d.ts | 9 +- src/renderer/services/ipc.service.ts | 28 ++++++ .../services/maps-downloader.service.ts | 22 ++--- src/renderer/services/maps-manager.service.ts | 70 ++++++-------- src/shared/models/archive.interface.ts | 4 + .../models/ipc/ipc-request.interface.ts | 9 +- .../models/ipc/ipc-response.interface.ts | 6 +- .../models/maps/bsm-local-map.interface.ts | 11 +++ 24 files changed, 498 insertions(+), 178 deletions(-) create mode 100644 src/main/models/archive.class.ts create mode 100644 src/main/services/ipc.service.ts create mode 100644 src/renderer/components/progress-bar/text-progress-bar.component.tsx create mode 100644 src/shared/models/archive.interface.ts diff --git a/package-lock.json b/package-lock.json index 69d89f18..f06803bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@tippyjs/react": "^4.2.6", "@types/react-virtualized-auto-sizer": "^1.0.1", "@types/react-window": "^1.8.5", + "@types/recursive-readdir": "^2.2.1", "archiver": "^5.3.1", "dateformat": "^5.0.3", "dot-prop": "^7.2.0", @@ -34,6 +35,7 @@ "react-router-dom": "^6.3.0", "react-virtualized-auto-sizer": "^1.0.7", "react-window": "^1.8.8", + "recursive-readdir": "^2.2.3", "regedit": "^5.1.1", "rfdc": "^1.3.0", "rxjs": "^7.5.6", @@ -2793,8 +2795,7 @@ "node_modules/@types/node": { "version": "17.0.23", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "dev": true + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -2889,6 +2890,14 @@ "@types/react": "*" } }, + "node_modules/@types/recursive-readdir": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/recursive-readdir/-/recursive-readdir-2.2.1.tgz", + "integrity": "sha512-Xd+Ptc4/F2ueInqy5yK2FI5FxtwwbX2+VZpcg+9oYsFJVen8qQKGapCr+Bi5wQtHU1cTXT8s+07lo/nKPgu8Gg==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -15749,6 +15758,17 @@ "node": ">= 0.10" } }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -21082,8 +21102,7 @@ "@types/node": { "version": "17.0.23", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "dev": true + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" }, "@types/parse-json": { "version": "4.0.0", @@ -21178,6 +21197,14 @@ "@types/react": "*" } }, + "@types/recursive-readdir": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/recursive-readdir/-/recursive-readdir-2.2.1.tgz", + "integrity": "sha512-Xd+Ptc4/F2ueInqy5yK2FI5FxtwwbX2+VZpcg+9oYsFJVen8qQKGapCr+Bi5wQtHU1cTXT8s+07lo/nKPgu8Gg==", + "requires": { + "@types/node": "*" + } + }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -30786,6 +30813,14 @@ "resolve": "^1.9.0" } }, + "recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "requires": { + "minimatch": "^3.0.5" + } + }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", diff --git a/package.json b/package.json index 714e5408..6f364b39 100644 --- a/package.json +++ b/package.json @@ -228,6 +228,7 @@ "@tippyjs/react": "^4.2.6", "@types/react-virtualized-auto-sizer": "^1.0.1", "@types/react-window": "^1.8.5", + "@types/recursive-readdir": "^2.2.1", "archiver": "^5.3.1", "dateformat": "^5.0.3", "dot-prop": "^7.2.0", @@ -250,6 +251,7 @@ "react-router-dom": "^6.3.0", "react-virtualized-auto-sizer": "^1.0.7", "react-window": "^1.8.8", + "recursive-readdir": "^2.2.3", "regedit": "^5.1.1", "rfdc": "^1.3.0", "rxjs": "^7.5.6", diff --git a/src/main/ipcs/bs-maps-ipcs.ts b/src/main/ipcs/bs-maps-ipcs.ts index 88f9733e..2abc2284 100644 --- a/src/main/ipcs/bs-maps-ipcs.ts +++ b/src/main/ipcs/bs-maps-ipcs.ts @@ -1,24 +1,21 @@ -import { ipcMain } from "electron"; + import { LocalMapsManagerService } from "../services/additional-content/local-maps-manager.service"; import { UtilsService } from "../services/utils.service"; import { BSVersion } from "shared/bs-version.interface"; import { IpcRequest } from "shared/models/ipc"; import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface"; import { BsvMapDetail } from "shared/models/maps"; +import { IpcService } from "../services/ipc.service"; +import { from } from "rxjs"; -ipcMain.on('get-version-maps', (event, request: IpcRequest) => { - const utilsService = UtilsService.getInstance(); +const ipc = IpcService.getInstance(); + +ipc.on('load-version-maps', async (request: IpcRequest, reply) => { const localMaps = LocalMapsManagerService.getInstance(); - - localMaps.getMaps(request.args).then(maps => { - utilsService.ipcSend(request.responceChannel, {success: true, data: maps}); - }).catch(() => { - utilsService.ipcSend(request.responceChannel, {success: false}); - }) - + reply(localMaps.getMaps(request.args)); }); -ipcMain.on("verion-have-maps-linked", async (event, request: IpcRequest) => { +ipc.on("verion-have-maps-linked", async (request: IpcRequest) => { const utils = UtilsService.getInstance(); const maps = LocalMapsManagerService.getInstance(); @@ -26,7 +23,7 @@ ipcMain.on("verion-have-maps-linked", async (event, request: IpcRequest) => { +ipc.on("link-version-maps", async (request: IpcRequest<{version: BSVersion, keepMaps: boolean}>) => { const utils = UtilsService.getInstance(); const maps = LocalMapsManagerService.getInstance(); @@ -38,7 +35,7 @@ ipcMain.on("link-version-maps", async (event, request: IpcRequest<{version: BSVe }); -ipcMain.on("unlink-version-maps", async (event, request: IpcRequest<{version: BSVersion, keepMaps: boolean}>) => { +ipc.on("unlink-version-maps", async (request: IpcRequest<{version: BSVersion, keepMaps: boolean}>) => { const utils = UtilsService.getInstance(); const maps = LocalMapsManagerService.getInstance(); @@ -50,40 +47,22 @@ ipcMain.on("unlink-version-maps", async (event, request: IpcRequest<{version: BS }); -ipcMain.on("delete-maps", async (event, request: IpcRequest<{maps: BsmLocalMap[]}>) => { - const utils = UtilsService.getInstance(); +ipc.on("delete-maps", async (request: IpcRequest, reply) => { const maps = LocalMapsManagerService.getInstance(); - - maps.deleteMaps(request.args.maps).then(() => { - utils.ipcSend(request.responceChannel, {success: true}); - }).catch(err => { - utils.ipcSend(request.responceChannel, {success: false, error: err}); - }); + reply(maps.deleteMaps(request.args)); }); -ipcMain.on("export-maps", async (event, request: IpcRequest<{version: BSVersion, maps: BsmLocalMap[], outPath: string}>) => { - const utils = UtilsService.getInstance(); +ipc.on("export-maps", async (request: IpcRequest<{version: BSVersion, maps: BsmLocalMap[], outPath: string}>, reply) => { const maps = LocalMapsManagerService.getInstance(); - - maps.exportMaps(request.args.version, request.args.maps, request.args.outPath).then(() => { - utils.ipcSend(request.responceChannel, {success: true}); - }).catch(err => { - utils.ipcSend(request.responceChannel, {success: false, error: err}); - }); + reply(await maps.exportMaps(request.args.version, request.args.maps, request.args.outPath)); }); -ipcMain.on("download-map", async (event, request: IpcRequest<{map: BsvMapDetail, version: BSVersion}>) => { - const utils = UtilsService.getInstance(); +ipc.on("download-map", async (request: IpcRequest<{map: BsvMapDetail, version: BSVersion}>, reply) => { const maps = LocalMapsManagerService.getInstance(); - - maps.downloadMap(request.args.map, request.args.version).then(() => { - utils.ipcSend(request.responceChannel, {success: true}); - }).catch(err => { - utils.ipcSend(request.responceChannel, {success: false, error: err}); - }); + reply(from(maps.downloadMap(request.args.map, request.args.version))) }); -ipcMain.on("one-click-install-map", async (event, request: IpcRequest) => { +ipc.on("one-click-install-map", async (request: IpcRequest) => { const utils = UtilsService.getInstance(); const maps = LocalMapsManagerService.getInstance(); @@ -94,7 +73,7 @@ ipcMain.on("one-click-install-map", async (event, request: IpcRequest) => { +ipc.on("register-maps-deep-link", async (request: IpcRequest) => { const maps = LocalMapsManagerService.getInstance(); const utils = UtilsService.getInstance(); @@ -109,7 +88,7 @@ ipcMain.on("register-maps-deep-link", async (event, request: IpcRequest) = }); -ipcMain.on("unregister-maps-deep-link", async (event, request: IpcRequest) => { +ipc.on("unregister-maps-deep-link", async (request: IpcRequest) => { const maps = LocalMapsManagerService.getInstance(); const utils = UtilsService.getInstance(); @@ -124,7 +103,7 @@ ipcMain.on("unregister-maps-deep-link", async (event, request: IpcRequest) }); -ipcMain.on("is-map-deep-links-enabled", async (event, request: IpcRequest) => { +ipc.on("is-map-deep-links-enabled", async (request: IpcRequest) => { const maps = LocalMapsManagerService.getInstance(); const utils = UtilsService.getInstance(); diff --git a/src/main/models/archive.class.ts b/src/main/models/archive.class.ts new file mode 100644 index 00000000..841dcbcb --- /dev/null +++ b/src/main/models/archive.class.ts @@ -0,0 +1,78 @@ +import archiver from "archiver"; +import { createWriteStream } from "fs"; +import { Observable } from "rxjs"; +import recursive from "recursive-readdir"; +import { lstatSync } from "fs"; +import * as _path from "path"; +import { ArchiveProgress } from "shared/models/archive.interface"; + +export class Archive{ + + private archive: archiver.Archiver; + private readonly output: string; + + private readonly directories: string[] = []; + private readonly files: string[] = []; + + constructor(output: string, options?: archiver.ArchiverOptions){ + this.output = output; + this.initArchive(options); + } + + private initArchive(options?: archiver.ArchiverOptions): void{ + const defaultOptions: archiver.ArchiverOptions = { + zlib: {level: 9} + }; + + this.archive = archiver("zip", {...defaultOptions, ...options}); + } + + private async loadTotalFiles(): Promise{ + let totalFiles = this.files.length; + for(const path of this.directories){ + const files = await recursive(path); + totalFiles += files.length; + } + return totalFiles; + } + + public addDirectory(path: string, destPath?: string|false): void{ + this.directories.push(path); + destPath = destPath === false ? false : _path.basename(path); + this.archive.directory(path, destPath); + } + + public addFile(path: string, destPath?: string): void{ + this.files.push(path); + destPath = destPath ||= _path.basename(path); + this.archive.file(path, {name: destPath}); + } + + + public finalize(): Observable{ + + const progress: ArchiveProgress = { + totalFiles: 0, + prossesedFiles: 0 + }; + + return new Observable(observer => { + (async () => { + + progress.totalFiles = await this.loadTotalFiles(); + + this.archive.on("entry", e => { + if(e.stats.isDirectory()){ return; } + progress.prossesedFiles++; + observer.next(progress); + }); + + this.archive.pipe(createWriteStream(this.output)); + + this.archive.on("error", err => observer.error(err)); + this.archive.finalize().then(() => observer.complete()); + })(); + }); + } + +} \ No newline at end of file diff --git a/src/main/preload.ts b/src/main/preload.ts index 69143b69..00ec0e3e 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -1,21 +1,23 @@ import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron'; - -export type Channels = any; +import { IpcChannel } from 'shared/models/ipc/ipc-response.interface'; contextBridge.exposeInMainWorld('electron', { ipcRenderer: { - sendMessage(channel: Channels, args: unknown[]) { + sendMessage(channel: IpcChannel, args: unknown[]) { ipcRenderer.send(channel, args); }, - on(channel: Channels, func: (...args: unknown[]) => void) { + on(channel: IpcChannel, func: (...args: unknown[]) => void) { const subscription = (_event: IpcRendererEvent, ...args: unknown[]) => func(...args); ipcRenderer.on(channel, subscription); return () => ipcRenderer.removeListener(channel, subscription); }, - once(channel: Channels, func: (...args: unknown[]) => void) { + once(channel: IpcChannel, func: (...args: unknown[]) => void) { ipcRenderer.once(channel, (_event, ...args) => func(...args)); }, + removeAllListeners(channel: IpcChannel) { + ipcRenderer.removeAllListeners(channel); + } }, }); diff --git a/src/main/services/additional-content/local-maps-manager.service.ts b/src/main/services/additional-content/local-maps-manager.service.ts index 5b31ef11..972593c5 100644 --- a/src/main/services/additional-content/local-maps-manager.service.ts +++ b/src/main/services/additional-content/local-maps-manager.service.ts @@ -1,13 +1,13 @@ import path from "path"; import { BSVersion } from "shared/bs-version.interface"; import { BsvMapDetail, RawMapInfoData } from "shared/models/maps"; -import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface"; +import { BsmLocalMap, BsmLocalMapsProgress, DeleteMapsProgress } from "shared/models/maps/bsm-local-map.interface"; import { BSLocalVersionService } from "../bs-local-version.service"; import { InstallationLocationService } from "../installation-location.service"; import { UtilsService } from "../utils.service"; import crypto from "crypto"; import { lstatSync, symlinkSync, unlinkSync, readdirSync, createWriteStream } from "fs"; -import { copySync } from "fs-extra"; +import { copy, copySync } from "fs-extra"; import StreamZip from "node-stream-zip"; import { RequestService } from "../request.service"; import sanitize from "sanitize-filename"; @@ -17,6 +17,9 @@ import log from 'electron-log'; import { WindowManagerService } from "../window-manager.service"; import { ipcMain } from "electron"; import { IpcRequest } from 'shared/models/ipc'; +import { Observable } from "rxjs"; +import { defer } from "rxjs"; +import { Archive } from "../../models/archive.class"; export class LocalMapsManagerService { @@ -62,6 +65,7 @@ export class LocalMapsManagerService { } public async getMapsFolderPath(version?: BSVersion): Promise{ + if(version){ return path.join(await this.localVersion.getVersionPath(version), this.LEVELS_ROOT_FOLDER, this.CUSTOM_LEVELS_FOLDER); } const sharedMapsPath = path.join(this.installLocation.sharedMapsPath, this.CUSTOM_LEVELS_FOLDER); if(!(await this.utils.pathExist(sharedMapsPath))){ @@ -125,14 +129,36 @@ export class LocalMapsManagerService { } - public async getMaps(version?: BSVersion): Promise{ - const levelsFolder = await this.getMapsFolderPath(version); + public getMaps(version?: BSVersion): Observable{ - const levelsPath = (await this.utils.pathExist(levelsFolder)) ? this.utils.listDirsInDir(levelsFolder, true) : []; + const progression: BsmLocalMapsProgress = { + total: 0, + loaded: 0, + maps: [] + }; - const mapsInfo = await Promise.all(levelsPath.map(levelPath => this.loadMapInfoFromPath(levelPath))); + return new Observable(observer => { + (async () => { + const levelsFolder = await this.getMapsFolderPath(version); - return mapsInfo.filter(info => !!info); + const levelsPaths = (await this.utils.pathExist(levelsFolder)) ? this.utils.listDirsInDir(levelsFolder, true) : []; + + progression.total = levelsPaths.length; + + for(const levelPath of levelsPaths){ + const mapInfo = await this.loadMapInfoFromPath(levelPath); + if(mapInfo){ + progression.maps.push(mapInfo); + progression.loaded = progression.maps.length; + observer.next({...progression, maps: []}); + } + } + + observer.next(progression); + + observer.complete(); + })(); + }); } public async versionIsLinked(version: BSVersion): Promise{ @@ -174,25 +200,37 @@ export class LocalMapsManagerService { this.utils.createFolderIfNotExist(versionMapsPath); if(keepMaps){ - copySync(sharedMapsPath, versionMapsPath); + await copy(sharedMapsPath, versionMapsPath); } } - public async deleteMaps(maps: BsmLocalMap[]){ + public deleteMaps(maps: BsmLocalMap[]): Observable{ const mapsFolders = maps.map(map => map.path); const mapsHashsToDelete = maps.map(map => map.hash); - for(const folder of mapsFolders){ - const { hash } = await this.loadMapInfoFromPath(folder); - if(!mapsHashsToDelete.includes(hash)){ continue; } - await this.utils.deleteFolder(folder); - } - + return new Observable(observer => { + (async () => { + const progress: DeleteMapsProgress = { total: maps.length, deleted: 0 }; + try{ + for(const folder of mapsFolders){ + const detail = await this.loadMapInfoFromPath(folder); + if(!mapsHashsToDelete.includes(detail?.hash)){ continue; } + await this.utils.deleteFolder(folder); + progress.deleted++; + observer.next(progress); + } + }catch(e){ + console.log(e); + observer.error(e); + } + observer.complete(); + })(); + }); } - public async downloadMap(map: BsvMapDetail, version?: BSVersion): Promise{ + public async downloadMap(map: BsvMapDetail, version?: BSVersion): Promise{ if(!map.versions.at(0).hash){ throw "Cannot download map, no hash found"; } @@ -215,34 +253,26 @@ export class LocalMapsManagerService { unlinkSync(zipPath); - return mapPath; + const localMap = await this.loadMapInfoFromPath(mapPath); + localMap.bsaverInfo = map; + + return localMap; } public async exportMaps(version: BSVersion, maps: BsmLocalMap[], outPath: string){ - const output = createWriteStream(outPath); - const archive = archiver("zip", {zlib: {level: 9}}); - - archive.pipe(output); - archive.on("error", (e) => {throw e}); + const archive = new Archive(outPath); if(!maps || maps.length === 0){ - const mapsFolder = await this.getMapsFolderPath(version); - archive.directory(mapsFolder, false); - + archive.addDirectory(mapsFolder, false); } else{ - const mapsFolders = maps.map(map => map.path); - - for(const folder of mapsFolders){ - archive.directory(folder, path.basename(folder)); - } - + mapsFolders.forEach(maps => archive.addDirectory(maps)); } - await archive.finalize(); + return archive.finalize() } @@ -260,7 +290,7 @@ export class LocalMapsManagerService { this.utils.createFolderIfNotExist(versionMapsPath); - copySync(downloadedMap, path.join(versionMapsPath, path.basename(downloadedMap)), {overwrite: true}); + copySync(downloadedMap.path, path.join(versionMapsPath, path.basename(downloadedMap.path)), {overwrite: true}); } diff --git a/src/main/services/additional-content/local-playlists-manager.service.ts b/src/main/services/additional-content/local-playlists-manager.service.ts index 3955efb5..ca40a768 100644 --- a/src/main/services/additional-content/local-playlists-manager.service.ts +++ b/src/main/services/additional-content/local-playlists-manager.service.ts @@ -163,7 +163,7 @@ export class LocalPlaylistsManagerService { ...res.value, current: null, downloadedMaps: [...res.value.downloadedMaps, map], - mapsPath: [...res.value.mapsPath, mapPath], + mapsPath: [...res.value.mapsPath, mapPath.path], progression }); diff --git a/src/main/services/bs-installer.service.ts b/src/main/services/bs-installer.service.ts index 39ba74e1..9f5f1452 100644 --- a/src/main/services/bs-installer.service.ts +++ b/src/main/services/bs-installer.service.ts @@ -28,7 +28,7 @@ export class BSInstallerService{ this.localVersionService = BSLocalVersionService.getInstance(); this.windows = WindowManagerService.getInstance(); - this.windows.getWindows("index.html")?.on("close", () => { + this.windows.getWindow("index.html")?.on("close", () => { this.killDownloadProcess(); }); } diff --git a/src/main/services/ipc.service.ts b/src/main/services/ipc.service.ts new file mode 100644 index 00000000..7f7665ea --- /dev/null +++ b/src/main/services/ipc.service.ts @@ -0,0 +1,65 @@ +import { IpcResponse, IpcRequest } from "shared/models/ipc"; +import { ipcMain } from "electron"; +import { Observable } from "rxjs"; +import { IpcChannel, IpcCompleteChannel, IpcErrorChannel } from "shared/models/ipc/ipc-response.interface"; +import { AppWindow } from "shared/models/window-manager/app-window.model"; +import { WindowManagerService } from "./window-manager.service"; +import { IpcReplier } from "shared/models/ipc/ipc-request.interface"; + +export class IpcService { + + private static instance: IpcService; + + public static getInstance(): IpcService { + if (!IpcService.instance) { IpcService.instance = new IpcService(); } + return IpcService.instance; + } + + private readonly windows: WindowManagerService; + + private constructor() { + this.windows = WindowManagerService.getInstance(); + } + + private getErrorChannel(channel: IpcChannel): IpcErrorChannel { + return `${channel}_error`; + } + + private getCompleteChannel(channel: IpcChannel): IpcCompleteChannel { + return `${channel}_complete`; + } + + private buildProxyListener(listener: (req: IpcRequest, replier: IpcReplier) => void) { + + return (event: Electron.IpcMainEvent, req: IpcRequest) => { + const window = this.windows.getAppWindowFromWebContents(event.sender); + const replier = (data: Observable) => this.connectStream(req.responceChannel, window, data); + listener(req, replier); + } + + } + + public send(channel: IpcChannel, window: AppWindow, response?: T|Error): void{ + this.windows.getWindow(window).webContents.send(channel, response); + } + + public connectStream(channel: IpcChannel, window: AppWindow, observable: Observable): void{ + observable.subscribe(data => { + this.send(channel, window, data); + }, error => { + console.log("LAAAA 2", error); + this.send(this.getErrorChannel(channel), window, error); + }, () => { + this.send(this.getCompleteChannel(channel), window); + }); + } + + public on(channel: IpcChannel, listener: (req: IpcRequest, replier: IpcReplier) => void): void{ + ipcMain.on(channel, this.buildProxyListener(listener)); + } + + public once(channel: IpcChannel, listener: (req: IpcRequest, replier: IpcReplier) => void): void{ + ipcMain.once(channel, this.buildProxyListener(listener)); + } + +} \ No newline at end of file diff --git a/src/main/services/thrid-party/beat-saver/beat-saver.service.ts b/src/main/services/thrid-party/beat-saver/beat-saver.service.ts index 660e98d1..087f2861 100644 --- a/src/main/services/thrid-party/beat-saver/beat-saver.service.ts +++ b/src/main/services/thrid-party/beat-saver/beat-saver.service.ts @@ -32,8 +32,7 @@ export class BeatSaverService { return res; }, [] as BsvMapDetail[]); - for(const hashs of chunkHash){ - + await Promise.all(chunkHash.map(async hashs => { const res = await this.bsaverApi.getMapsDetailsByHashs(hashs); if(res.status === 200){ @@ -42,7 +41,7 @@ export class BeatSaverService { this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail); }); } - } + })); return mapDetails; } diff --git a/src/main/services/window-manager.service.ts b/src/main/services/window-manager.service.ts index e81a3ec4..c0e59752 100644 --- a/src/main/services/window-manager.service.ts +++ b/src/main/services/window-manager.service.ts @@ -75,8 +75,12 @@ export class WindowManagerService{ }); } - public getWindows(window: AppWindow): BrowserWindow{ + public getWindow(window: AppWindow): BrowserWindow{ return this.windows.get(window); } + public getAppWindowFromWebContents(sender: Electron.WebContents): AppWindow{ + return Array.from(this.windows.entries()).find(([key, value]) => value.webContents.id === sender.id)[0]; + } + } \ No newline at end of file diff --git a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx index 6ab4ea1c..53e659a7 100644 --- a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx @@ -9,7 +9,15 @@ import { MapsDownloaderService } from "renderer/services/maps-downloader.service import { VariableSizeList } from "react-window" import { MapsRow } from "./maps-row.component" import { BehaviorSubject } from "rxjs" -import { debounceTime } from "rxjs/operators" +import { debounceTime, last, map, mergeMap, throttleTime } from "rxjs/operators" +import { BeatSaverService } from "renderer/services/thrird-partys/beat-saver.service" +import { OsDiagnosticService } from "renderer/services/os-diagnostic.service" +import { useTranslation } from "renderer/hooks/use-translation.hook" +import BeatWaitingImg from "../../../../assets/images/apngs/beat-waiting.png" +import BeatConflict from "../../../../assets/images/apngs/beat-conflict.png" +import { BsmImage } from "../shared/bsm-image.component" +import { BsmButton } from "../shared/bsm-button.component" +import TextProgressBar from "../progress-bar/text-progress-bar.component" type Props = { version: BSVersion, @@ -22,22 +30,34 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc const mapsManager = MapsManagerService.getInstance(); const mapsDownloader = MapsDownloaderService.getInstance(); + const bsaver = BeatSaverService.getInstance(); + const os = OsDiagnosticService.getInstance(); + const t = useTranslation(); const ref = useRef(null) const isVisible = useInView(ref, {once: true}); const [maps, setMaps] = useState(null); const [subs] = useState([]); - const [selectedMaps$] = useState>(new BehaviorSubject([])); + const [selectedMaps$] = useState(new BehaviorSubject([])); const [itemPerRow, setItemPerRow] = useState(2); const [listHeight, setListHeight] = useState(0); + const [loadPercent$] = useState(new BehaviorSubject(0)); + useImperativeHandle(forwardRef ,()=>({ deleteMaps(){ - const mapsToDelete = selectedMaps$.value.length === 0 ? maps : selectedMaps$.value - mapsManager.deleteMaps(mapsToDelete, version).then(res => res && removeMapsFromList(mapsToDelete)); + const mapsToDelete = selectedMaps$.value.length === 0 ? maps : selectedMaps$.value; + mapsManager.deleteMaps(mapsToDelete, version).then(res => { + if(!res){ return; } + removeMapsFromList(mapsToDelete); + selectedMaps$.next([]); + }); }, exportMaps(){ - mapsManager.exportMaps(version, selectedMaps$.value) + mapsManager.exportMaps(version, selectedMaps$.value); + }, + getMaps(){ + return maps; } }), [selectedMaps$.value, maps, version]); @@ -47,13 +67,17 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc loadMaps(); subs.push(mapsManager.versionLinked$.subscribe(loadMaps)); subs.push(mapsManager.versionUnlinked$.subscribe(loadMaps)); - mapsDownloader.addOnMapDownloadedListener(loadMaps); + mapsDownloader.addOnMapDownloadedListener((map, targerVersion) => { + if(targerVersion !== version){ return; } + setMaps(maps => maps ? [map, ...maps] : [map]); + }); } return () => { setMaps(() => null); + loadPercent$.next(0); subs.forEach(s => s.unsubscribe()); - mapsDownloader.removeOnMapDownloadedListene(loadMaps); + mapsDownloader.removeOnMapDownloadedListener(loadMaps); } }, [isVisible, version]); @@ -86,7 +110,32 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc }, [isVisible, itemPerRow]) const loadMaps = () => { - subs.push(mapsManager.getMaps(version).subscribe(localMaps => setMaps(() => [...localMaps]))); + + setMaps(() => null); + loadPercent$.next(0); + + const loadMapsObs$ = mapsManager.getMaps(version); + + loadMapsObs$.pipe(map(progess => { + console.log(progess); + return Math.floor(((progess.loaded / progess.total) * 100)); + })).subscribe(percent => loadPercent$.next(percent)); + + subs.push(loadMapsObs$.pipe( + last(), + mergeMap(async progress => { + if(os.isOffline){ return progress.maps; } + const maps = progress.maps; + const details = await bsaver.getMapDetailsFromHashs(maps.map(map => map.hash)); + return maps.map(map => { + map.bsaverInfo = details.find(d => d.versions.at(0).hash === map.hash); + return map; + }) + }) + ).subscribe({ + next: maps => setMaps(() => maps), + complete: () => loadPercent$.next(0) + })); } const removeMapsFromList = (mapsToRemove: BsmLocalMap[]) => { @@ -100,8 +149,6 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc const onMapSelected = useCallback((map: BsmLocalMap) => { - console.log(map); - const mapsCopy = [...selectedMaps$.value]; if(mapsCopy.some(selectedMap => selectedMap.hash === map.hash)){ const i = mapsCopy.findIndex(selectedMap => selectedMap.hash === map.hash); @@ -111,12 +158,9 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc mapsCopy.push(map); } - console.log(mapsCopy); - selectedMaps$.next(mapsCopy); - }, [selectedMaps$.value]); - console.log(selectedMaps$.value); + }, [selectedMaps$.value]); const isMapFitFilter = (map: BsmLocalMap): boolean => { @@ -257,6 +301,30 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc return res; })(); + if(!maps){ + return ( +
+
+ + {t("modals.download-maps.loading-maps")} + +
+
+ ); + } + + if(!maps.length){ + return ( +
+
+ + {t("pages.version-viewer.maps.tabs.maps.empty-maps.text")} + {e.preventDefault(); mapsDownloader.openDownloadMapModal(version)}}/> +
+
+ ); + } + return (
108} itemCount={preppedMaps.length} itemData={preppedMaps} layout="vertical" style={{scrollbarGutter: "stable both-edges"}} itemKey={(i, data) => data[i].map(map => map.hash).join()}> diff --git a/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx b/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx index 6606288c..3e5e1484 100644 --- a/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx @@ -59,7 +59,7 @@ export function MapsPlaylistsPanel({version}: Props) { } const handleMapsAddClick = () => { - mapsDownloader.openDownloadMapModal(version); + mapsDownloader.openDownloadMapModal(version, mapsRef.current.getMaps?.()); } const renderTab = (props: DetailedHTMLProps, HTMLLIElement>, text: string, index: number): JSX.Element => { diff --git a/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx b/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx index 911310b1..b7c831cf 100644 --- a/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx @@ -19,11 +19,11 @@ import equal from "fast-deep-equal/es6"; import { ProgressBarService } from "renderer/services/progress-bar.service"; import { useTranslation } from "renderer/hooks/use-translation.hook"; import { OsDiagnosticService } from "renderer/services/os-diagnostic.service"; +import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface"; -export const DownloadMapsModal: ModalComponent = ({data}) => { +export const DownloadMapsModal: ModalComponent = ({resolver, data: { ownedMaps, version }}) => { const beatSaver = BeatSaverService.getInstance(); - const mapsManager = MapsManagerService.getInstance(); const mapsDownloader = MapsDownloaderService.getInstance(); const progressBar = ProgressBarService.getInstance(); const os = OsDiagnosticService.getInstance(); @@ -36,7 +36,7 @@ export const DownloadMapsModal: ModalComponent = ({data}) => { const [query, setQuery] = useState(""); const [maps, setMaps] = useState([]); const [sortOrder, setSortOrder] = useState(BSV_SORT_ORDER.at(0)); - const [ownedMapHashs, setOwnedMapHashs] = useState([]); + const [ownedMapHashs, setOwnedMapHashs] = useState(ownedMaps?.map(map => map.hash) ?? []); const [loading, setLoading] = useState(false); const isOnline = useObservable(os.isOnline$); const [searchParams, setSearchParams] = useState({ @@ -58,13 +58,12 @@ export const DownloadMapsModal: ModalComponent = ({data}) => { useEffect(() => { - mapsManager.getMaps(data, false).toPromise().then(maps => setOwnedMapHashs(maps.map(map => map.hash))); - - const onMapDownloaded = (map: BsvMapDetail, verion: BSVersion) => { - if(!equal(verion, data) || !map?.versions){ return; } - const downloadedHash = map.versions.at(0).hash; + const onMapDownloaded = (map: BsmLocalMap, targerVersion: BSVersion) => { + if(!equal(targerVersion, version)){ return; } + const downloadedHash = map.hash; setOwnedMapHashs((prev) => [...prev, downloadedHash]); } + mapsDownloader.addOnMapDownloadedListener(onMapDownloaded); if(mapsDownloader.isDownloading){ @@ -72,7 +71,7 @@ export const DownloadMapsModal: ModalComponent = ({data}) => { } return () => { - mapsDownloader.removeOnMapDownloadedListene(onMapDownloaded); + mapsDownloader.removeOnMapDownloadedListener(onMapDownloaded); progressBar.setStyle(null); } }, []) @@ -99,7 +98,7 @@ export const DownloadMapsModal: ModalComponent = ({data}) => { const isMapOwned = map.versions.some(version => ownedMapHashs.includes(version.hash)); const isDownloading = map.id === currentDownload?.map?.id; - const inQueue = mapsInQueue.some(toDownload => equal(toDownload.version, data) && toDownload.map.id === map.id); + const inQueue = mapsInQueue.some(toDownload => equal(toDownload.version, version) && toDownload.map.id === map.id); return ( = ({data}) => { } const handleDownloadMap = useCallback((map: BsvMapDetail) => { - mapsDownloader.addMapToDownload({map, version: data}) + mapsDownloader.addMapToDownload({map, version}) }, []); const handleCancelDownload = useCallback((map: BsvMapDetail) => { - mapsDownloader.removeMapToDownload({map, version: data}); + mapsDownloader.removeMapToDownload({map, version}); }, []); const handleSortChange = (newSort: string) => { @@ -170,7 +169,7 @@ export const DownloadMapsModal: ModalComponent = ({data}) => { {e.preventDefault(); handleSearch()}}/>
-
    +
      {maps.length === 0 ? (
       diff --git a/src/renderer/components/progress-bar/text-progress-bar.component.tsx b/src/renderer/components/progress-bar/text-progress-bar.component.tsx new file mode 100644 index 00000000..87d996ef --- /dev/null +++ b/src/renderer/components/progress-bar/text-progress-bar.component.tsx @@ -0,0 +1,20 @@ +import { CSSProperties } from "react"; +import { useObservable } from "renderer/hooks/use-observable.hook"; +import { Observable } from "rxjs" + +type Props = { + value$: Observable, + className?: string, + style?: CSSProperties +} + +export default function TextProgressBar({value$, className, style}: Props) { + + const value = useObservable(value$); + + const prefix = typeof value === "number" ? "%" : ""; + + return ( + {`${value}${prefix}`} + ) +} diff --git a/src/renderer/components/shared/bsm-image.component.tsx b/src/renderer/components/shared/bsm-image.component.tsx index 3fc99e5d..038cdbb6 100644 --- a/src/renderer/components/shared/bsm-image.component.tsx +++ b/src/renderer/components/shared/bsm-image.component.tsx @@ -37,6 +37,6 @@ export const BsmImage = forwardRef(({className, image, errorImage, placeholder, return ( // @ts-ignore - onClick?.(e)} alt=" "/> + onClick?.(e)} alt=" " decoding="async"/> ) }) diff --git a/src/renderer/preload.d.ts b/src/renderer/preload.d.ts index b8b7e9d0..bce2f371 100644 --- a/src/renderer/preload.d.ts +++ b/src/renderer/preload.d.ts @@ -1,15 +1,16 @@ -import { Channels, ReplyChannels } from 'main/preload'; +import { IpcChannel } from "shared/models/ipc/ipc-response.interface"; declare global { interface Window { electron: { ipcRenderer: { - sendMessage(channel: Channels, args: any): void; + sendMessage(channel: IpcChannel, args: any): void; on( - channel: ReplyChannels, + channel: IpcChannel, func: (...args: any) => void ): (() => void) | undefined; - once(channel: ReplyChannels, func: (...args: any) => void): void; + once(channel: IpcChannel, func: (...args: any) => void): void; + removeAllListeners(channel: IpcChannel): void; }; }; } diff --git a/src/renderer/services/ipc.service.ts b/src/renderer/services/ipc.service.ts index f8bbe1b1..2f9ee7c1 100644 --- a/src/renderer/services/ipc.service.ts +++ b/src/renderer/services/ipc.service.ts @@ -1,5 +1,7 @@ +import { defaultIfEmpty } from "rxjs/operators"; import { Observable } from "rxjs"; import { IpcRequest, IpcResponse } from "shared/models/ipc"; +import { identity } from "rxjs"; export class IpcService { @@ -47,4 +49,30 @@ export class IpcService { return obs; } + // TODO : Convert all IPCs calls to V2 + + public sendV2(channel: string, request?: IpcRequest, defaultValue?: T): Observable{ + if(!request){ request = {args: null, responceChannel: null}; } + if(!request.responceChannel){ request.responceChannel = `${channel}_responce_${new Date().getTime()}`; } + + const completeChannel = `${request.responceChannel}_complete`; + const errorChannel = `${request.responceChannel}_error`; + + const obs = new Observable(observer => { + window.electron.ipcRenderer.on(request.responceChannel, (res: T) => observer.next(res)); + window.electron.ipcRenderer.on(errorChannel, (err: Error) => observer.error(err)); + window.electron.ipcRenderer.on(completeChannel, () => observer.complete()); + }).pipe(defaultValue ? defaultIfEmpty(defaultValue) : identity); + + window.electron.ipcRenderer.once(completeChannel, () => { + window.electron.ipcRenderer.removeAllListeners(request.responceChannel); + window.electron.ipcRenderer.removeAllListeners(errorChannel); + window.electron.ipcRenderer.removeAllListeners(completeChannel); + }); + + window.electron.ipcRenderer.sendMessage(channel, request); + + return obs; + } + } \ No newline at end of file diff --git a/src/renderer/services/maps-downloader.service.ts b/src/renderer/services/maps-downloader.service.ts index 297319b0..ddeb3db8 100644 --- a/src/renderer/services/maps-downloader.service.ts +++ b/src/renderer/services/maps-downloader.service.ts @@ -10,6 +10,7 @@ import { IpcService } from "./ipc.service"; import { OsDiagnosticService } from "./os-diagnostic.service"; import equal from "fast-deep-equal/es6"; import { CSSProperties } from "react"; +import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface"; export class MapsDownloaderService { @@ -28,7 +29,7 @@ export class MapsDownloaderService { private readonly mapsQueue$: BehaviorSubject = new BehaviorSubject([]); private readonly currentDownload$: BehaviorSubject = new BehaviorSubject(null); private queueMaxLenght = 0; - private downloadedListerners: ((map: BsvMapDetail, version: BSVersion) => void)[] = []; + private downloadedListerners: ((map: BsmLocalMap, version: BSVersion) => void)[] = []; public readonly progressBarStyle: CSSProperties = {zIndex: 100000, position: "fixed", bottom: "10px", right: 0}; private constructor(){ @@ -50,10 +51,10 @@ export class MapsDownloaderService { while(this.mapsQueue$.value.at(0)){ const toDownload = this.mapsQueue$.value.at(0); this.currentDownload$.next(toDownload); - const downloaded = await this.downloadMap(toDownload.map, toDownload.version); + const downloaded = await this.downloadMap(toDownload.map, toDownload.version).toPromise(); if(downloaded){ - this.downloadedListerners.forEach(func => func(toDownload.map, toDownload.version)); + this.downloadedListerners.forEach(func => func(downloaded, toDownload.version)); } const newArr = [...this.mapsQueue$.value]; @@ -67,14 +68,13 @@ export class MapsDownloaderService { this.progressBar.hide(true); } - private async downloadMap(map: BsvMapDetail, version: BSVersion): Promise{ - if(this.os.isOffline){ return false } - const res = await this.ipc.send("download-map", {args: {map, version}}); - return res.success; + private downloadMap(map: BsvMapDetail, version: BSVersion): Observable{ + if(this.os.isOffline){ return null } + return this.ipc.sendV2("download-map", {args: {map, version}}); } - public async openDownloadMapModal(version?: BSVersion): Promise>{ - const res = await this.modals.openModal(DownloadMapsModal, version); + public async openDownloadMapModal(version?: BSVersion, ownedMaps: BsmLocalMap[] = []): Promise>{ + const res = await this.modals.openModal(DownloadMapsModal, {version, ownedMaps}); this.progressBar.setStyle(null); return res; } @@ -109,11 +109,11 @@ export class MapsDownloaderService { return this.mapsQueue$.asObservable(); } - public addOnMapDownloadedListener(func: (map: BsvMapDetail, version: BSVersion) => void){ + public addOnMapDownloadedListener(func: (map: BsmLocalMap, version: BSVersion) => void){ this.downloadedListerners.push(func); } - public removeOnMapDownloadedListene(func: (map: BsvMapDetail, version: BSVersion) => void){ + public removeOnMapDownloadedListener(func: (map: BsmLocalMap, version: BSVersion) => void){ const funcIndex = this.downloadedListerners.indexOf(func); if(funcIndex < 0){ return; } this.downloadedListerners.splice(funcIndex, 1); diff --git a/src/renderer/services/maps-manager.service.ts b/src/renderer/services/maps-manager.service.ts index 49382ebd..b4ba9147 100644 --- a/src/renderer/services/maps-manager.service.ts +++ b/src/renderer/services/maps-manager.service.ts @@ -2,8 +2,7 @@ import { LinkMapsModal } from "renderer/components/modal/modal-types/link-maps-m import { UnlinkMapsModal } from "renderer/components/modal/modal-types/unlink-maps-modal.component"; import { Subject, Observable } from "rxjs"; import { BSVersion } from "shared/bs-version.interface"; -import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface"; -import { BeatSaverService } from "./thrird-partys/beat-saver.service"; +import { BsmLocalMapsProgress, BsmLocalMap, DeleteMapsProgress } from "shared/models/maps/bsm-local-map.interface"; import { IpcService } from "./ipc.service"; import { ModalExitCode, ModalService } from "./modale.service"; import { DeleteMapsModal } from "renderer/components/modal/modal-types/delete-maps-modal.component"; @@ -11,6 +10,10 @@ import { ProgressBarService } from "./progress-bar.service"; import { OpenSaveDialogOption } from "shared/models/ipc"; import { NotificationService } from "./notification.service"; import { ConfigurationService } from "./configuration.service"; +import { ArchiveProgress } from "shared/models/archive.interface"; +import { map, last, catchError } from "rxjs/operators"; +import { of } from "rxjs"; +import { ProgressionInterface } from "shared/models/progress-bar"; export class MapsManagerService { @@ -24,7 +27,6 @@ export class MapsManagerService { public static readonly REMEMBER_CHOICE_DELETE_MAP_KEY = "not-confirm-delete-map" private readonly ipcService: IpcService; - private readonly bsaver: BeatSaverService; private readonly modal: ModalService; private readonly progressBar: ProgressBarService; private readonly notifications: NotificationService; @@ -35,32 +37,14 @@ export class MapsManagerService { private constructor(){ this.ipcService = IpcService.getInstance(); - this.bsaver = BeatSaverService.getInstance(); this.modal = ModalService.getInsance(); this.progressBar = ProgressBarService.getInstance(); this.notifications = NotificationService.getInstance(); this.config = ConfigurationService.getInstance(); } - public getMaps(version?: BSVersion, withDetails = true): Observable{ - return new Observable(obs => { - this.ipcService.send("get-version-maps", {args: version}).then(res => { - if(!res.success){ return obs.complete();} - - obs.next(res.data); - - if(!withDetails){ return obs.complete(); } - - this.bsaver.getMapDetailsFromHashs(res.data.map(localMap => localMap.hash)).then(mapsDetails => { - mapsDetails.forEach(details => { - const corespondingMap = res.data.find(localMap => localMap.hash === details.versions.find(details => details?.hash === localMap.hash)?.hash); - if(!corespondingMap){ return; } - res.data.find(localMap => localMap.hash === details.versions.find(details => details?.hash === localMap.hash)?.hash).bsaverInfo = details - }); - obs.next(res.data); - }) - }); - }); + public getMaps(version?: BSVersion): Observable{ + return this.ipcService.sendV2("load-version-maps", {args: version}, {loaded: 0, total: 0, maps: []}); } public versionHaveMapsLinked(version: BSVersion): Promise{ @@ -129,17 +113,15 @@ export class MapsManagerService { const showProgressBar = this.progressBar.require(); - if(showProgressBar){ - this.progressBar.showFake(.008); - } + const progress$ = this.ipcService.sendV2("delete-maps", {args: maps}).pipe(map(progress => (progress.deleted / progress.total) * 100)); - const res = await this.ipcService.send("delete-maps", {args: {maps}}); + progress$.subscribe(console.log); - if(showProgressBar){ - this.progressBar.hide(true); - } + showProgressBar && this.progressBar.show(progress$, true); - return res.success; + progress$.toPromise().finally(() => this.progressBar.hide(true)); + + return progress$.pipe(last(), map(() => true), catchError(() => of(false))).toPromise().catch(() => false); } public async exportMaps(version: BSVersion, maps?: BsmLocalMap[]): Promise{ @@ -152,18 +134,22 @@ export class MapsManagerService { if(!resFile.success){ return; } - this.progressBar.showFake(.008); - - const resExport = await this.ipcService.send("export-maps", {args: {version, maps, outPath: resFile.data}}); - if(!resExport.success && resExport.error.title){ - const {title, msg} = resExport.error; - this.notifications.notifyError({title, desc: msg}); - } - else { + const exportProgress$: Observable = await this.ipcService.sendV2("export-maps", {args: {version, maps, outPath: resFile.data}}).pipe( + map(p => { + return { progression: (p.prossesedFiles / p.totalFiles) * 100, label: `${p.prossesedFiles} / ${p.totalFiles}` } as ProgressionInterface + }) + ); + + this.progressBar.show(exportProgress$, true); + + await exportProgress$.toPromise().catch(e => { + this.notifications.notifyError({title: "notifications.types.error", desc: e.message}); + }).then(() => { this.notifications.notifySuccess({title: "Export terminé 🎉", duration: 3000}); - } - this.progressBar.complete(); - this.progressBar.hide(true); + this.progressBar.complete(); + this.progressBar.hide(true); + }); + } public async isDeepLinksEnabled(): Promise{ diff --git a/src/shared/models/archive.interface.ts b/src/shared/models/archive.interface.ts new file mode 100644 index 00000000..438801b3 --- /dev/null +++ b/src/shared/models/archive.interface.ts @@ -0,0 +1,4 @@ +export interface ArchiveProgress{ + totalFiles: number; + prossesedFiles: number; +} \ No newline at end of file diff --git a/src/shared/models/ipc/ipc-request.interface.ts b/src/shared/models/ipc/ipc-request.interface.ts index bcf754c9..c97881eb 100644 --- a/src/shared/models/ipc/ipc-request.interface.ts +++ b/src/shared/models/ipc/ipc-request.interface.ts @@ -1,4 +1,9 @@ +import { Observable } from "rxjs"; +import { IpcResponse } from "./ipc-response.interface"; + export interface IpcRequest{ args?: T, - responceChannel?: string -} \ No newline at end of file + responceChannel?: string, +} + +export type IpcReplier= (data: Observable) => void; \ No newline at end of file diff --git a/src/shared/models/ipc/ipc-response.interface.ts b/src/shared/models/ipc/ipc-response.interface.ts index ac8c512e..e9a3b175 100644 --- a/src/shared/models/ipc/ipc-response.interface.ts +++ b/src/shared/models/ipc/ipc-response.interface.ts @@ -4,4 +4,8 @@ export interface IpcResponse{ data?: T, error?: BsmException, success: boolean, -} \ No newline at end of file +} + +export type IpcChannel = string; +export type IpcErrorChannel = IpcChannel & `${string}_error`; +export type IpcCompleteChannel = IpcChannel & `${string}_complete`; \ No newline at end of file diff --git a/src/shared/models/maps/bsm-local-map.interface.ts b/src/shared/models/maps/bsm-local-map.interface.ts index 2c353465..e4d3e1d6 100644 --- a/src/shared/models/maps/bsm-local-map.interface.ts +++ b/src/shared/models/maps/bsm-local-map.interface.ts @@ -8,4 +8,15 @@ export interface BsmLocalMap { rawInfo: RawMapInfoData, bsaverInfo?: BsvMapDetail path: string +} + +export interface BsmLocalMapsProgress { + total: number, + loaded: number, + maps: BsmLocalMap[], +} + +export interface DeleteMapsProgress { + total: number, + deleted: number } \ No newline at end of file From 3aacd7575b2e91a36ef805ab1cd83ff05b8a401b Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 21 Feb 2023 01:00:39 +0100 Subject: [PATCH 19/23] fix oneclick map not work when no BS versions intalled --- .../services/additional-content/local-maps-manager.service.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/services/additional-content/local-maps-manager.service.ts b/src/main/services/additional-content/local-maps-manager.service.ts index 972593c5..fbf0e169 100644 --- a/src/main/services/additional-content/local-maps-manager.service.ts +++ b/src/main/services/additional-content/local-maps-manager.service.ts @@ -280,6 +280,10 @@ export class LocalMapsManagerService { const downloadedMap = await this.downloadMap(map); + const sharedMapsPath = await this.getMapsFolderPath(); + + copySync(downloadedMap.path, path.join(sharedMapsPath, path.basename(downloadedMap.path)), {overwrite: true}); + const versions = await this.localVersion.getInstalledVersions(); for(const version of versions){ From 8d28c3cfc80d5fe90c9b47d0b4a69ded69a46cfb Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 21 Feb 2023 01:28:42 +0100 Subject: [PATCH 20/23] oneclick map not install map in unlinked versions --- .../services/additional-content/local-maps-manager.service.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/services/additional-content/local-maps-manager.service.ts b/src/main/services/additional-content/local-maps-manager.service.ts index fbf0e169..972593c5 100644 --- a/src/main/services/additional-content/local-maps-manager.service.ts +++ b/src/main/services/additional-content/local-maps-manager.service.ts @@ -280,10 +280,6 @@ export class LocalMapsManagerService { const downloadedMap = await this.downloadMap(map); - const sharedMapsPath = await this.getMapsFolderPath(); - - copySync(downloadedMap.path, path.join(sharedMapsPath, path.basename(downloadedMap.path)), {overwrite: true}); - const versions = await this.localVersion.getInstalledVersions(); for(const version of versions){ From 6b2879d9dc21e5ce550aab76cbac83a3db743700 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Tue, 21 Feb 2023 01:39:17 +0100 Subject: [PATCH 21/23] bumb version --- release/app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/app/package.json b/release/app/package.json index 1ba06a43..4f3c8f7a 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "bs-manager", - "version": "1.0.1", + "version": "1.0.2-alpha.1", "description": "A foundation for scalable desktop apps", "main": "./dist/main/main.js", "author": { From dc70d2889f743f902d713ca600c4c065bfb4e2af Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Fri, 24 Feb 2023 01:10:15 +0100 Subject: [PATCH 22/23] fix unlink maps EN translation --- assets/jsons/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index aeab9e36..712517ca 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -45,7 +45,7 @@ "link-maps": { "tooltips": { "link": "Link maps", - "unlink": "Unling maps" + "unlink": "Unlink maps" } } }, From 5641c25cc1cf0d2533fa3cef33e90586182637e1 Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Fri, 24 Feb 2023 01:12:46 +0100 Subject: [PATCH 23/23] bumb version --- release/app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/app/package.json b/release/app/package.json index 4f3c8f7a..bbf34f8a 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "bs-manager", - "version": "1.0.2-alpha.1", + "version": "1.0.2", "description": "A foundation for scalable desktop apps", "main": "./dist/main/main.js", "author": {