From a22486193ef49113851fab6f277d50f796ecc636 Mon Sep 17 00:00:00 2001 From: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> Date: Tue, 21 Mar 2023 18:28:18 +0100 Subject: Add buttons to download PRs (#203) * feat: Add button to download Mods PR Simply opens the browser on the repo download link * feat: Add button to download Launcher PR Uses existing function to fetch nightly.link link and opens it in browser * refactor: Open Mods PR download link via TS as opposed to having a link directly This way it acts the same way as the Launcher PR download button. Reason behind this change being consistent UI style. * chore: Revert introduced formatting changes Those were added by accident, whoops * fix: Remove introduced unused dependency * fix: Remove unused dependencies --- src-vue/src/components/PullRequestsSelector.vue | 10 ++++++++-- src-vue/src/plugins/modules/pull_requests.ts | 21 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'src-vue/src') diff --git a/src-vue/src/components/PullRequestsSelector.vue b/src-vue/src/components/PullRequestsSelector.vue index 58a355f4..9ddefc7e 100644 --- a/src-vue/src/components/PullRequestsSelector.vue +++ b/src-vue/src/components/PullRequestsSelector.vue @@ -15,6 +15,7 @@ Install + Download {{ pull_request.number }}: {{ pull_request.title }} @@ -41,6 +42,7 @@

Install + Download {{ pull_request.number }}: {{ pull_request.title }} @@ -54,8 +56,6 @@ import { defineComponent } from 'vue' import { PullRequestType } from '../../../src-tauri/bindings/PullRequestType'; import { PullsApiResponseElement } from '../../../src-tauri/bindings/PullsApiResponseElement'; -import { invoke } from "@tauri-apps/api"; -import { ElNotification } from "element-plus"; export default defineComponent({ name: 'PullRequestsSelector', @@ -80,6 +80,12 @@ export default defineComponent({ async getPullRequests(pull_request_type: PullRequestType) { this.$store.commit('getPullRequests', pull_request_type); }, + async downloadLauncherPR(pull_request: PullsApiResponseElement) { + this.$store.commit('downloadLauncherPR', pull_request); + }, + async downloadModsPR(pull_request: PullsApiResponseElement) { + this.$store.commit('downloadModsPR', pull_request); + }, async installLauncherPR(pull_request: PullsApiResponseElement) { this.$store.commit('installLauncherPR', pull_request); }, diff --git a/src-vue/src/plugins/modules/pull_requests.ts b/src-vue/src/plugins/modules/pull_requests.ts index 573856ad..64c85b77 100644 --- a/src-vue/src/plugins/modules/pull_requests.ts +++ b/src-vue/src/plugins/modules/pull_requests.ts @@ -1,5 +1,5 @@ import { ElNotification } from "element-plus"; -import { invoke } from "@tauri-apps/api"; +import { invoke, shell } from "@tauri-apps/api"; import { PullsApiResponseElement } from "../../../../src-tauri/bindings/PullsApiResponseElement"; import { PullRequestType } from '../../../../src-tauri/bindings/PullRequestType'; import { store } from "../store"; @@ -41,6 +41,25 @@ export const pullRequestModule = { }); }); }, + async downloadLauncherPR(state: PullRequestStoreState, pull_request: PullsApiResponseElement) { + await invoke("get_launcher_download_link", { pullRequest: pull_request }) + .then((url) => { + // Open URL in default HTTPS handler (i.e. default browser) + shell.open(url); + }) + .catch((error) => { + ElNotification({ + title: 'Error', + message: error, + type: 'error', + position: 'bottom-right' + }); + }); + }, + async downloadModsPR(state: PullRequestStoreState, pull_request: PullsApiResponseElement) { + let url = `https://github.com/${pull_request.head.repo.full_name}/archive/refs/heads/${pull_request.head.ref}.zip` + shell.open(url); + }, async installLauncherPR(state: PullRequestStoreState, pull_request: PullsApiResponseElement) { // Send notification telling the user to wait for the process to finish const notification = ElNotification({ -- cgit v1.2.3 From 5e096f84e59eae0ed6b7bb758149c491c87538a6 Mon Sep 17 00:00:00 2001 From: Rémy Raes Date: Wed, 22 Mar 2023 21:46:12 +0100 Subject: feat: Refresh statistics (#228) * feat: fetch stats every 5 minutes and ping front with received information * feat: update front on stats reception * style: format code * fix: Add comment --------- Co-authored-by: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> --- src-tauri/src/constants.rs | 5 ++++- src-tauri/src/main.rs | 13 ++++++++++++- src-vue/src/plugins/store.ts | 5 +++++ 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'src-vue/src') diff --git a/src-tauri/src/constants.rs b/src-tauri/src/constants.rs index 57a10e02..7b13206a 100644 --- a/src-tauri/src/constants.rs +++ b/src-tauri/src/constants.rs @@ -1,6 +1,6 @@ // This file stores various global constants values - use const_format::concatcp; +use std::time::Duration; // FlightCore user agent for web requests pub const APP_USER_AGENT: &str = concatcp!("FlightCore/", env!("CARGO_PKG_VERSION")); @@ -34,3 +34,6 @@ pub const PULLS_API_ENDPOINT_LAUNCHER: &str = "https://api.github.com/repos/R2Northstar/NorthstarLauncher/pulls"; pub const PULLS_API_ENDPOINT_MODS: &str = "https://api.github.com/repos/R2Northstar/NorthstarMods/pulls"; + +// Statistics (players and servers counts) refresh delay +pub const REFRESH_DELAY: Duration = Duration::from_secs(5 * 60); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index d2f7951d..d5fef9cb 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -10,7 +10,7 @@ use std::{ }; use app::{ - constants::{APP_USER_AGENT, MASTER_SERVER_URL, SERVER_BROWSER_ENDPOINT}, + constants::{APP_USER_AGENT, MASTER_SERVER_URL, REFRESH_DELAY, SERVER_BROWSER_ENDPOINT}, *, }; @@ -96,6 +96,17 @@ fn main() { } }); + // Emit updated player and server count to GUI + let app_handle = app.app_handle(); + tauri::async_runtime::spawn(async move { + loop { + sleep(REFRESH_DELAY).await; + app_handle + .emit_all("northstar-statistics", get_server_player_count().await) + .unwrap(); + } + }); + Ok(()) }) .manage(Counter(Default::default())) diff --git a/src-vue/src/plugins/store.ts b/src-vue/src/plugins/store.ts index 8671d12b..d5b7c5d8 100644 --- a/src-vue/src/plugins/store.ts +++ b/src-vue/src/plugins/store.ts @@ -455,6 +455,11 @@ function _initializeListeners(state: any) { listen("northstar-running-ping", function (evt: TauriEvent) { state.northstar_is_running = evt.payload as boolean; }); + + listen("northstar-statistics", function (evt: TauriEvent<{Ok: [number, number]}>) { + state.player_count = evt.payload.Ok[0]; + state.server_count = evt.payload.Ok[1]; + }); } /** -- cgit v1.2.3 From 12741098da937ab55d2e1292631217b3a21a3ffa Mon Sep 17 00:00:00 2001 From: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> Date: Mon, 27 Mar 2023 17:58:26 +0200 Subject: fix: Address regression around persistent store (#227) * fix: Pin tauri-plugin-store package to same commit Pin npm package to same commit as Rust crate * fix: Attempt using newest plugin store commit * fix: Perform explicit save to store on each change This seems to resolve the issue around no longer writing changes to store on close as now values are written on each change. * chore: Pin dependencies to specific commit Instead of tracking a branch, track a specific commit --- docs/DEVELOPMENT.md | 1 + src-tauri/Cargo.lock | 4 ++-- src-tauri/Cargo.toml | 2 +- src-tauri/src/main.rs | 3 +-- src-vue/package-lock.json | 25 ++++++++++++++++--------- src-vue/package.json | 2 +- src-vue/src/plugins/store.ts | 3 +++ src-vue/src/views/SettingsView.vue | 6 ++++-- 8 files changed, 29 insertions(+), 17 deletions(-) (limited to 'src-vue/src') diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 8dbb1cea..0eada12c 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -145,6 +145,7 @@ const persistentStore = new Store('flight-core-settings.json'); // Save change in persistent store await persistentStore.set('northstar-release-canal', { value: "NorthstarReleasecandidate" }); +await persistentStore.save(); // explicit save to disk // Grab Northstar release canal value from store if exists var persistent_northstar_release_canal = (await persistentStore.get('northstar-release-canal')) as any; diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index c461ae0a..b407f7bb 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3969,8 +3969,8 @@ dependencies = [ [[package]] name = "tauri-plugin-store" -version = "0.0.0" -source = "git+https://github.com/tauri-apps/tauri-plugin-store?rev=9bd993aa67766596638bbfd91e79a1bf8f632014#9bd993aa67766596638bbfd91e79a1bf8f632014" +version = "0.1.0" +source = "git+https://github.com/tauri-apps/plugins-workspace?rev=5a6abd3203dc94c38f96d0c4bf7ecbef399f8c25#5a6abd3203dc94c38f96d0c4bf7ecbef399f8c25" dependencies = [ "log", "serde", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index e8a1d726..8c1415e6 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -43,7 +43,7 @@ sysinfo = "0.26.2" # HTTP requests reqwest = { version = "0.11", features = ["blocking"] } # Persistent store for settings -tauri-plugin-store = { git = "https://github.com/tauri-apps/tauri-plugin-store", rev = "9bd993aa67766596638bbfd91e79a1bf8f632014" } +tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "5a6abd3203dc94c38f96d0c4bf7ecbef399f8c25" } # JSON5 parsing support (allows comments in JSON) json5 = "0.4.1" # Async recursion for recursive mod install diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index fb3a8bb2..dfceece7 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -40,7 +40,6 @@ mod thunderstore; use thunderstore::query_thunderstore_packages_api; use tauri::{Manager, Runtime}; -use tauri_plugin_store::PluginBuilder; use tokio::time::sleep; #[derive(Default)] @@ -67,7 +66,7 @@ fn main() { )); tauri::Builder::default() - .plugin(PluginBuilder::default().build()) + .plugin(tauri_plugin_store::Builder::default().build()) .setup(|app| { let app_handle = app.app_handle(); tauri::async_runtime::spawn(async move { diff --git a/src-vue/package-lock.json b/src-vue/package-lock.json index bf311673..a652b266 100644 --- a/src-vue/package-lock.json +++ b/src-vue/package-lock.json @@ -11,7 +11,7 @@ "@element-plus/icons-vue": "^2.0.9", "element-plus": "^2.2.17", "marked": "^4.1.1", - "tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#dev", + "tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#9bd993aa67766596638bbfd91e79a1bf8f632014", "vue": "^3.2.37", "vue-router": "^4.1.5", "vuex": "^4.0.2" @@ -107,11 +107,11 @@ } }, "node_modules/@tauri-apps/api": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.2.0.tgz", - "integrity": "sha512-lsI54KI6HGf7VImuf/T9pnoejfgkNoXveP14pVV7XarrQ46rOejIVJLFqHI9sRReJMGdh2YuCoI3cc/yCWCsrw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.1.0.tgz", + "integrity": "sha512-n13pIqdPd3KtaMmmAcrU7BTfdMtIlGNnfZD0dNX8L4p8dgmuNyikm6JAA+yCpl9gqq6I8x5cV2Y0muqdgD0cWw==", "engines": { - "node": ">= 14.6.0", + "node": ">= 12.22.0", "npm": ">= 6.6.0", "yarn": ">= 1.19.1" }, @@ -1064,13 +1064,20 @@ } }, "node_modules/tauri-plugin-store-api": { - "version": "0.0.0", - "resolved": "git+ssh://git@github.com/tauri-apps/tauri-plugin-store.git#916165e4e4ad9821095584dc02ecd9c295cc9971", - "license": "MIT or APACHE-2.0", + "version": "0.1.0", + "resolved": "git+ssh://git@github.com/tauri-apps/tauri-plugin-store.git#9bd993aa67766596638bbfd91e79a1bf8f632014", + "integrity": "sha512-X0cDDcEVLY2X8qCLISgAjzuBKDn7bJkj4S7LnXbEPFbPRe+NzhmFGHSAdFCuQuPzQYjmrVg18mZx9NAg4GBHag==", + "license": "MIT", "dependencies": { - "@tauri-apps/api": "^1.2.0" + "@tauri-apps/api": "1.1.0", + "tslib": "2.4.0" } }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", diff --git a/src-vue/package.json b/src-vue/package.json index fbe3fc1a..674ca132 100644 --- a/src-vue/package.json +++ b/src-vue/package.json @@ -12,7 +12,7 @@ "@element-plus/icons-vue": "^2.0.9", "element-plus": "^2.2.17", "marked": "^4.1.1", - "tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#dev", + "tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#9bd993aa67766596638bbfd91e79a1bf8f632014", "vue": "^3.2.37", "vue-router": "^4.1.5", "vuex": "^4.0.2" diff --git a/src-vue/src/plugins/store.ts b/src-vue/src/plugins/store.ts index d5b7c5d8..caa46bee 100644 --- a/src-vue/src/plugins/store.ts +++ b/src-vue/src/plugins/store.ts @@ -143,6 +143,7 @@ export const store = createStore({ // Save change in persistent store await persistentStore.set('game-install', { value: game_install }); + await persistentStore.save(); // explicit save to disk // Check for Northstar install store.commit('checkNorthstarUpdates'); @@ -307,6 +308,7 @@ export const store = createStore({ // Save change in persistent store await persistentStore.set('northstar-release-canal', { value: state.northstar_release_canal }); + await persistentStore.save(); // explicit save to disk // Update current state so that update check etc can be performed store.commit("checkNorthstarUpdates"); @@ -407,6 +409,7 @@ async function _initializeApp(state: any) { // Save change in persistent store await persistentStore.set('game-install', { value: typedResult }); + await persistentStore.save(); // explicit save to disk // Update UI store state.game_path = typedResult.game_path; diff --git a/src-vue/src/views/SettingsView.vue b/src-vue/src/views/SettingsView.vue index c93d69ff..4e816740 100644 --- a/src-vue/src/views/SettingsView.vue +++ b/src-vue/src/views/SettingsView.vue @@ -78,9 +78,10 @@ export default defineComponent({ get(): boolean { return this.$store.state.enableReleasesSwitch; }, - set(value: boolean): void { + async set(value: boolean): Promise { this.$store.state.enableReleasesSwitch = value; persistentStore.set('northstar-releases-switching', { value }); + await persistentStore.save(); // explicit save to disk // When disabling switch, we switch release canal to stable release, to avoid users being // stuck with release candidate after disabling release switching. @@ -93,9 +94,10 @@ export default defineComponent({ get(): number { return this.$store.state.mods_per_page; }, - set(value: number) { + async set(value: number) { this.$store.state.mods_per_page = value; persistentStore.set('thunderstore-mods-per-page', { value }); + await persistentStore.save(); // explicit save to disk } } }, -- cgit v1.2.3 From 4cdfc0ea04844681de078d26f44321cb3c3b05c5 Mon Sep 17 00:00:00 2001 From: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> Date: Mon, 27 Mar 2023 18:10:46 +0200 Subject: feat: Generate FlightCore release notes (#188) * feat: Generate FlightCore release notes * fix: Remove leftover comment * fix: Add missing semantic commit type * fix: Re-add newlines accidentally removed in merge * refactor: Remove contributors section Will re-add a proper implementation in a later PR. * fix: Revert accidentally modified line * docs: Update comments * fix: Use correct user-agent * fix: Put unknown commits into "Other" section Previously they were just dropped * refactor: Move constant string array to right file * fix: Remove debug prints * refactor: Move lib import to start of file * refactor: Use wrapper type kinda needed by selector in frontend. Allows for still passing full object to backend for future extensability * fix: Generate missing wrapper TS interface * fix: Add title and message to notification * refactor: Move constant to consts file * fix: Fix formatting * fix: Remove unnecessary property declaration --- src-tauri/bindings/Tag.ts | 3 + src-tauri/bindings/TagWrapper.ts | 4 + src-tauri/src/constants.rs | 8 ++ src-tauri/src/github/mod.rs | 176 ++++++++++++++++++++++++++++++++++++ src-tauri/src/main.rs | 3 + src-vue/src/views/DeveloperView.vue | 95 +++++++++++++++++++ 6 files changed, 289 insertions(+) create mode 100644 src-tauri/bindings/Tag.ts create mode 100644 src-tauri/bindings/TagWrapper.ts (limited to 'src-vue/src') diff --git a/src-tauri/bindings/Tag.ts b/src-tauri/bindings/Tag.ts new file mode 100644 index 00000000..adbbff33 --- /dev/null +++ b/src-tauri/bindings/Tag.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export interface Tag { name: string, } \ No newline at end of file diff --git a/src-tauri/bindings/TagWrapper.ts b/src-tauri/bindings/TagWrapper.ts new file mode 100644 index 00000000..f9f56a51 --- /dev/null +++ b/src-tauri/bindings/TagWrapper.ts @@ -0,0 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Tag } from "./Tag"; + +export interface TagWrapper { label: string, value: Tag, } \ No newline at end of file diff --git a/src-tauri/src/constants.rs b/src-tauri/src/constants.rs index 7b13206a..0f4e9ab4 100644 --- a/src-tauri/src/constants.rs +++ b/src-tauri/src/constants.rs @@ -29,6 +29,11 @@ pub const BLACKLISTED_MODS: [&str; 3] = [ // Titanfall2 game IDs on Origin/EA-App pub const TITANFALL2_ORIGIN_IDS: [&str; 2] = ["Origin.OFR.50.0001452", "Origin.OFR.50.0001456"]; +// Order in which the sections for release notes should be displayed +pub const SECTION_ORDER: [&str; 9] = [ + "feat", "fix", "docs", "style", "refactor", "build", "test", "chore", "other", +]; + // GitHub API endpoints for launcher/mods PRs pub const PULLS_API_ENDPOINT_LAUNCHER: &str = "https://api.github.com/repos/R2Northstar/NorthstarLauncher/pulls"; @@ -37,3 +42,6 @@ pub const PULLS_API_ENDPOINT_MODS: &str = // Statistics (players and servers counts) refresh delay pub const REFRESH_DELAY: Duration = Duration::from_secs(5 * 60); + +// Flightcore repo name and org name on GitHub +pub const FLIGHTCORE_REPO_NAME: &str = "R2NorthstarTools/FlightCore"; diff --git a/src-tauri/src/github/mod.rs b/src-tauri/src/github/mod.rs index 942f0db2..87ea629c 100644 --- a/src-tauri/src/github/mod.rs +++ b/src-tauri/src/github/mod.rs @@ -1,2 +1,178 @@ pub mod pull_requests; pub mod release_notes; + +use app::constants::{APP_USER_AGENT, FLIGHTCORE_REPO_NAME, SECTION_ORDER}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use ts_rs::TS; + +#[derive(Serialize, Deserialize, Debug, Clone, TS)] +#[ts(export)] +pub struct Tag { + name: String, +} + +/// Wrapper type needed for frontend +#[derive(Serialize, Deserialize, Debug, Clone, TS)] +#[ts(export)] +pub struct TagWrapper { + label: String, + value: Tag, +} + +#[derive(Debug, Deserialize)] +struct CommitInfo { + sha: String, + commit: Commit, +} + +#[derive(Debug, Deserialize)] +struct Commit { + message: String, +} + +#[derive(Debug, Deserialize)] +struct Comparison { + commits: Vec, +} + +/// Get a list of tags on the FlightCore repo +#[tauri::command] +pub fn get_list_of_tags() -> Result, String> { + // Set the repository name. + + // Create a `reqwest` client with a user agent. + let client = reqwest::blocking::Client::builder() + .user_agent(APP_USER_AGENT) + .build() + .unwrap(); + + // Fetch the list of tags for the repository as a `Vec`. + let tags_url = format!("https://api.github.com/repos/{}/tags", FLIGHTCORE_REPO_NAME); + let tags: Vec = client.get(&tags_url).send().unwrap().json().unwrap(); + + // Map each `Tag` element to a `TagWrapper` element with the desired label and `Tag` value. + let tag_wrappers: Vec = tags + .into_iter() + .map(|tag| TagWrapper { + label: tag.name.clone(), + value: tag, + }) + .collect(); + + Ok(tag_wrappers) +} + +/// Use GitHub API to compare two tags of the same repo against each other and get the resulting changes +#[tauri::command] +pub fn compare_tags(first_tag: Tag, second_tag: Tag) -> Result { + // Fetch the list of commits between the two tags. + + // Create a `reqwest` client with a user agent. + let client = reqwest::blocking::Client::builder() + .user_agent(APP_USER_AGENT) + .build() + .unwrap(); + + let repo = "R2NorthstarTools/FlightCore"; + + let mut full_patch_notes = "".to_string(); + + let mut patch_notes: Vec = [].to_vec(); + println!("{}", repo); + // let repo = "R2Northstar/NorthstarLauncher"; + let comparison_url = format!( + "https://api.github.com/repos/{}/compare/{}...{}", + repo, first_tag.name, second_tag.name + ); + + let comparison: Comparison = client.get(&comparison_url).send().unwrap().json().unwrap(); + let commits = comparison.commits; + + // Display the list of commits. + println!( + "Commits between {} and {}:", + first_tag.name, second_tag.name + ); + + // Iterate over all commits in the diff + for commit in commits { + println!( + " * {} : {}", + commit.sha, + commit.commit.message.split('\n').next().unwrap() + ); + patch_notes.push(format!( + "{}", + commit.commit.message.split('\n').next().unwrap() + )); + } + + full_patch_notes += &generate_flightcore_release_notes(patch_notes); + + Ok(full_patch_notes.to_string()) +} + +/// Generate release notes in the format used for FlightCore +fn generate_flightcore_release_notes(commits: Vec) -> String { + let grouped_commits = group_commits_by_type(commits); + let mut release_notes = String::new(); + + // Go over commit types and generate notes + for commit_type in SECTION_ORDER { + if let Some(commit_list) = grouped_commits.get(commit_type) { + if !commit_list.is_empty() { + let section_title = match commit_type { + "feat" => "**Features:**", + "fix" => "**Bug Fixes:**", + "docs" => "**Documentation:**", + "style" => "**Styles:**", + "refactor" => "**Code Refactoring:**", + "build" => "**Build:**", + "test" => "**Tests:**", + "chore" => "**Chores:**", + _ => "**Other:**", + }; + + release_notes.push_str(&format!("{}\n", section_title)); + + for commit_message in commit_list { + release_notes.push_str(&format!("- {}\n", commit_message)); + } + + release_notes.push_str("\n"); + } + } + } + + release_notes +} + +/// Group semantic commit messages by type +/// Commmit messages that are not formatted accordingly are marked as "other" +fn group_commits_by_type(commits: Vec) -> HashMap> { + let mut grouped_commits: HashMap> = HashMap::new(); + let mut other_commits: Vec = vec![]; + + for commit in commits { + let commit_parts: Vec<&str> = commit.splitn(2, ":").collect(); + if commit_parts.len() == 2 { + let commit_type = commit_parts[0].to_lowercase(); + let commit_description = commit_parts[1].trim().to_string(); + + // Check if known commit type + if SECTION_ORDER.contains(&commit_type.as_str()) { + let commit_list = grouped_commits.entry(commit_type.to_string()).or_default(); + commit_list.push(commit_description); + } else { + // otherwise add to list of "other" + other_commits.push(commit.to_string()); + } + } else { + other_commits.push(commit.to_string()); + } + } + grouped_commits.insert("other".to_string(), other_commits); + + grouped_commits +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index dfceece7..f4712cd4 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -21,6 +21,7 @@ use github::pull_requests::{ use github::release_notes::{ check_is_flightcore_outdated, get_newest_flightcore_version, get_northstar_release_notes, }; +use github::{compare_tags, get_list_of_tags}; mod repair_and_verify; use repair_and_verify::{ @@ -137,6 +138,8 @@ fn main() { delete_thunderstore_mod, open_repair_window, query_thunderstore_packages_api, + get_list_of_tags, + compare_tags, get_pull_requests_wrapper, apply_launcher_pr, apply_mods_pr, diff --git a/src-vue/src/views/DeveloperView.vue b/src-vue/src/views/DeveloperView.vue index 52117b8d..bca473fb 100644 --- a/src-vue/src/views/DeveloperView.vue +++ b/src-vue/src/views/DeveloperView.vue @@ -5,6 +5,38 @@ This page is designed for developers. Some of the buttons here can break your Northstar install if you do not know what you're doing! + + Get tags + + + + + + + + + + + Compare Tags + + + +

Basic:

@@ -53,6 +85,7 @@ import { defineComponent } from "vue"; import { invoke } from "@tauri-apps/api"; import { ElNotification } from "element-plus"; import { GameInstall } from "../utils/GameInstall"; +import { TagWrapper } from "../../../src-tauri/bindings/TagWrapper"; import PullRequestsSelector from "../components/PullRequestsSelector.vue"; export default defineComponent({ @@ -63,8 +96,30 @@ export default defineComponent({ data() { return { mod_to_install_field_string : "", + release_notes_text : "", + first_tag: { label: '', value: {name: ''} }, + second_tag: { label: '', value: {name: ''} }, + ns_release_tags: [] as TagWrapper[], } }, + computed: { + firstTag: { + get(): TagWrapper { + return this.first_tag; + }, + set(value: TagWrapper) { + this.first_tag = value; + } + }, + secondTag: { + get(): TagWrapper { + return this.second_tag; + }, + set(value: TagWrapper) { + this.second_tag = value; + } + }, + }, methods: { disableDevMode() { this.$store.commit('toggleDeveloperMode'); @@ -152,6 +207,46 @@ export default defineComponent({ }); }); }, + async getTags() { + await invoke("get_list_of_tags") + .then((message) => { + this.ns_release_tags = message; + ElNotification({ + title: "Done", + message: "Fetched tags", + type: 'success', + position: 'bottom-right' + }); + }) + .catch((error) => { + ElNotification({ + title: 'Error', + message: error, + type: 'error', + position: 'bottom-right' + }); + }); + }, + async compareTags() { + await invoke("compare_tags", {firstTag: this.firstTag.value, secondTag: this.secondTag.value}) + .then((message) => { + this.release_notes_text = message; + ElNotification({ + title: "Done", + message: "Generated release notes", + type: 'success', + position: 'bottom-right' + }); + }) + .catch((error) => { + ElNotification({ + title: 'Error', + message: error, + type: 'error', + position: 'bottom-right' + }); + }); + }, } }); -- cgit v1.2.3 From 428c300e9f42f8b9232f780d387292c1a94fcd23 Mon Sep 17 00:00:00 2001 From: Rémy Raes Date: Wed, 29 Mar 2023 00:45:16 +0200 Subject: feat: i18n (#182) * build: add vue-i18n dependency * feat: add i18n plugin to vue project * feat: use translations in play button * feat: translate play view * feat: translate menu items * feat: translate local mods view * feat: translate online mods view * feat: translate mods menu * feat: translate thunderstore mod card component * fix: remove useless "this" keyword * feat: translate settings view * fix: remove leftover test invocation * feat: add language selector component * feat: using language selector updates interface's language * feat: save language in persistent store on selector change * feat: initialize lang on app launch * refactor: move i18n code into App.mounted callback * feat: update interface language on app launch * feat: adjust language selection on language selector load * fix: this.$root can't be null * feat: translate store notifications * fix: add missing parameter to english translation * feat: translate "by" author keyword * feat: translate repair window * feat: translate repair window title * docs: add some documentation regarding localization * docs: explain how to add a new language * feat: translate Northstar release canal selector elements * docs: describe how to inject variable into translations * feat: translate "info" word * feat: translate popconfirm buttons * fix: remove "this" keyword * fix: save store when updating interface language --- docs/DEVELOPMENT.md | 60 + src-vue/package-lock.json | 1544 ++++++++++++++--------- src-vue/package.json | 1 + src-vue/src/App.vue | 25 +- src-vue/src/components/LanguageSelector.vue | 47 + src-vue/src/components/ModsMenu.vue | 14 +- src-vue/src/components/PlayButton.vue | 16 +- src-vue/src/components/ThunderstoreModCard.vue | 34 +- src-vue/src/i18n/lang/en.ts | 156 +++ src-vue/src/i18n/lang/fr.ts | 156 +++ src-vue/src/main.ts | 12 + src-vue/src/plugins/store.ts | 26 +- src-vue/src/utils/SortOptions.d.ts | 12 +- src-vue/src/views/PlayView.vue | 14 +- src-vue/src/views/RepairView.vue | 27 +- src-vue/src/views/SettingsView.vue | 47 +- src-vue/src/views/mods/LocalModsView.vue | 18 +- src-vue/src/views/mods/ThunderstoreModsView.vue | 4 +- 18 files changed, 1535 insertions(+), 678 deletions(-) create mode 100644 src-vue/src/components/LanguageSelector.vue create mode 100644 src-vue/src/i18n/lang/en.ts create mode 100644 src-vue/src/i18n/lang/fr.ts (limited to 'src-vue/src') diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 0eada12c..02832722 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -179,6 +179,66 @@ struct User { then simply run `cargo test`. The generated bindings are placed in `src-tauri/bindings/`. Make sure to add and commit them as well! +### Internationalization + +For FlightCore to be used by the largest number, its interface is translated in several languages; users can choose used language through FlightCore settings. + +Localization files are located in `src-vue/src/i18n/lang`. + +To add a new language, you have to create associated file, *e.g. `src-vue/src/i18n/lang/de.ts`*, and import it in the i18n application object in `main.ts`: +```javascript +import de from "./i18n/lang/de"; + +export const i18n = createI18n({ + locale: 'en', + fallbackLocale: 'en', + messages: { + en, fr, de + } +}); +``` + +There are different ways to use translations in views; in HTML template, invoke the `$t` method with translation key: + +```html +
+ {{ $t('menu.play') }} +
+``` + +For use in Typescript code (inside components), invoke the `this.$t` method: + +```javascript +return this.$t("play.button.select_game_dir"); +``` + +For Typescript code outside components, translations are still accessible: + +```javascript +import { i18n } from '../main'; +i18n.global.tc('notification.game_folder.new.text'); +``` + +--- + +It is possible to inject variables into translations: + +```javascript +channels: { + release: { + component: { + text: "Switched release channel to {canal}." + } + } +} +``` + +```javascript +return this.$t("channels.release.component.text", {canal: "MyCanalName"}); +``` + + + ## Other This repo uses [EditorConfig](https://editorconfig.org/) to define some basic formatting rules. Find a plugin for your IDE [here](https://editorconfig.org/#download). diff --git a/src-vue/package-lock.json b/src-vue/package-lock.json index a652b266..31cee6e0 100644 --- a/src-vue/package-lock.json +++ b/src-vue/package-lock.json @@ -1,7 +1,7 @@ { "name": "src-vue", "version": "0.0.0", - "lockfileVersion": 3, + "lockfileVersion": 2, "requires": true, "packages": { "": { @@ -13,6 +13,7 @@ "marked": "^4.1.1", "tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#9bd993aa67766596638bbfd91e79a1bf8f632014", "vue": "^3.2.37", + "vue-i18n": "^9.2.2", "vue-router": "^4.1.5", "vuex": "^4.0.2" }, @@ -25,9 +26,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", - "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", "bin": { "parser": "bin/babel-parser.js" }, @@ -36,9 +37,9 @@ } }, "node_modules/@ctrl/tinycolor": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.0.tgz", - "integrity": "sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", + "integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==", "engines": { "node": ">=10" } @@ -51,49 +52,74 @@ "vue": "^3.2.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz", - "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], + "node_modules/@floating-ui/core": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.0.2.tgz", + "integrity": "sha512-Skfy0YS3NJ5nV9us0uuPN0HDk1Q4edljaOhRBJGDWs9EBa7ZVMYBHRFlhLvvmwEoaIM9BlH6QJFn9/uZg0bACg==" + }, + "node_modules/@floating-ui/dom": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.7.tgz", + "integrity": "sha512-6RsqvCYe0AYWtsGvuWqCm7mZytnXAZCjWtsWu1Kg8dI3INvj/DbKlDsZO+mKSaQdPT12uxIW9W2dAWJkPx4Y5g==", + "dependencies": { + "@floating-ui/core": "^1.0.2" + } + }, + "node_modules/@intlify/core-base": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.2.2.tgz", + "integrity": "sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==", + "dependencies": { + "@intlify/devtools-if": "9.2.2", + "@intlify/message-compiler": "9.2.2", + "@intlify/shared": "9.2.2", + "@intlify/vue-devtools": "9.2.2" + }, "engines": { - "node": ">=12" + "node": ">= 14" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz", - "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], + "node_modules/@intlify/devtools-if": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.2.2.tgz", + "integrity": "sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==", + "dependencies": { + "@intlify/shared": "9.2.2" + }, "engines": { - "node": ">=12" + "node": ">= 14" } }, - "node_modules/@floating-ui/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.1.tgz", - "integrity": "sha512-LSqwPZkK3rYfD7GKoIeExXOyYx6Q1O4iqZWwIehDNuv3Dv425FIAE8PRwtAx1imEolFTHgBEcoFHm9MDnYgPCg==" + "node_modules/@intlify/message-compiler": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.2.2.tgz", + "integrity": "sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==", + "dependencies": { + "@intlify/shared": "9.2.2", + "source-map": "0.6.1" + }, + "engines": { + "node": ">= 14" + } }, - "node_modules/@floating-ui/dom": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.1.tgz", - "integrity": "sha512-Rt45SmRiV8eU+xXSB9t0uMYiQ/ZWGE/jumse2o3i5RGlyvcbqOF4q+1qBnzLE2kZ5JGhq0iMkcGXUKbFe7MpTA==", + "node_modules/@intlify/shared": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", + "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@intlify/vue-devtools": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz", + "integrity": "sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==", "dependencies": { - "@floating-ui/core": "^1.2.1" + "@intlify/core-base": "9.2.2", + "@intlify/shared": "9.2.2" + }, + "engines": { + "node": ">= 14" } }, "node_modules/@popperjs/core": { @@ -134,9 +160,9 @@ } }, "node_modules/@types/marked": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.8.tgz", - "integrity": "sha512-HVNzMT5QlWCOdeuBsgXP8EZzKUf0+AXzN+sLmjvaB3ZlLqO+e4u0uXrdw9ub69wBKFs+c6/pA4r9sy6cCDvImw==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.7.tgz", + "integrity": "sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw==", "dev": true }, "node_modules/@types/web-bluetooth": { @@ -158,90 +184,91 @@ } }, "node_modules/@volar/language-core": { - "version": "1.3.0-alpha.0", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.3.0-alpha.0.tgz", - "integrity": "sha512-W3uMzecHPcbwddPu4SJpUcPakRBK/y/BP+U0U6NiPpUX1tONLC4yCawt+QBJqtgJ+sfD6ztf5PyvPL3hQRqfOA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.0.11.tgz", + "integrity": "sha512-YwUYKxIyDc+Fq3kQ6BGGfkrKCG5JzE2Yr6vMxrxEXW2rg/gsq3JgMk/4sI8ybRsaTirhCB4V8+AIVYsvcRxgig==", "dev": true, "dependencies": { - "@volar/source-map": "1.3.0-alpha.0" + "@volar/source-map": "1.0.11", + "@vue/reactivity": "^3.2.45", + "muggle-string": "^0.1.0" } }, "node_modules/@volar/source-map": { - "version": "1.3.0-alpha.0", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.3.0-alpha.0.tgz", - "integrity": "sha512-jSdizxWFvDTvkPYZnO6ew3sBZUnS0abKCbuopkc0JrIlFbznWC/fPH3iPFIMS8/IIkRxq1Jh9VVG60SmtsdaMQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.0.11.tgz", + "integrity": "sha512-tkuV9MD+OuiZfHA0qZXrPdW6F7TvnpnuTan6Qe7UGUs9+sflezlMJdjaYdGgQObfP+06pcT1E3xdkOoi08ZyyQ==", "dev": true, "dependencies": { - "muggle-string": "^0.2.2" + "muggle-string": "^0.1.0" } }, "node_modules/@volar/typescript": { - "version": "1.3.0-alpha.0", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.3.0-alpha.0.tgz", - "integrity": "sha512-5UItyW2cdH2mBLu4RrECRNJRgtvvzKrSCn2y3v/D61QwIDkGx4aeil6x8RFuUL5TFtV6QvVHXnsOHxNgd+sCow==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.0.11.tgz", + "integrity": "sha512-mq7wDDAs0Eb43jev2FxbowuiwWqvL3kb+tar1we8VQbdabpyQ5dmbWPwo/IglevMmW3SKo1Et+6rqAeZpXNnPQ==", "dev": true, "dependencies": { - "@volar/language-core": "1.3.0-alpha.0" + "@volar/language-core": "1.0.11" } }, "node_modules/@volar/vue-language-core": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.2.0.tgz", - "integrity": "sha512-w7yEiaITh2WzKe6u8ZdeLKCUz43wdmY/OqAmsB/PGDvvhTcVhCJ6f0W/RprZL1IhqH8wALoWiwEh/Wer7ZviMQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.0.11.tgz", + "integrity": "sha512-A3ODs0/ua7BcpSSnE7KtO8bzWsYsbOJRyW2Q/2uktxlfHj8srln3JdgK/mNlIgfnWtACbE5K+EfMJOgJKv864A==", "dev": true, "dependencies": { - "@volar/language-core": "1.3.0-alpha.0", - "@volar/source-map": "1.3.0-alpha.0", - "@vue/compiler-dom": "^3.2.47", - "@vue/compiler-sfc": "^3.2.47", - "@vue/reactivity": "^3.2.47", - "@vue/shared": "^3.2.47", - "minimatch": "^6.1.6", - "muggle-string": "^0.2.2", + "@volar/language-core": "1.0.11", + "@volar/source-map": "1.0.11", + "@vue/compiler-dom": "^3.2.45", + "@vue/compiler-sfc": "^3.2.45", + "@vue/reactivity": "^3.2.45", + "@vue/shared": "^3.2.45", + "minimatch": "^5.1.0", "vue-template-compiler": "^2.7.14" } }, "node_modules/@volar/vue-typescript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.2.0.tgz", - "integrity": "sha512-zjmRi9y3J1EkG+pfuHp8IbHmibihrKK485cfzsHjiuvJMGrpkWvlO5WVEk8oslMxxeGC5XwBFE9AOlvh378EPA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.0.11.tgz", + "integrity": "sha512-jlnFPvBcTyPiAbGlgjhKK7fp3Q+Z7Z5eU1NTbTSS0lQC8Gog3sh2UxLAFG5Voe1gHIxasoOEPXzMR0CWF4bKbA==", "dev": true, "dependencies": { - "@volar/typescript": "1.3.0-alpha.0", - "@volar/vue-language-core": "1.2.0" + "@volar/typescript": "1.0.11", + "@volar/vue-language-core": "1.0.11" } }, "node_modules/@vue/compiler-core": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz", - "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz", + "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.47", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz", - "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz", + "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==", "dependencies": { - "@vue/compiler-core": "3.2.47", - "@vue/shared": "3.2.47" + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz", - "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz", + "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.47", - "@vue/compiler-dom": "3.2.47", - "@vue/compiler-ssr": "3.2.47", - "@vue/reactivity-transform": "3.2.47", - "@vue/shared": "3.2.47", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-ssr": "3.2.45", + "@vue/reactivity-transform": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -249,83 +276,83 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz", - "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz", + "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==", "dependencies": { - "@vue/compiler-dom": "3.2.47", - "@vue/shared": "3.2.47" + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/@vue/devtools-api": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", - "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz", + "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==" }, "node_modules/@vue/reactivity": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz", - "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz", + "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==", "dependencies": { - "@vue/shared": "3.2.47" + "@vue/shared": "3.2.45" } }, "node_modules/@vue/reactivity-transform": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz", - "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz", + "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.47", - "@vue/shared": "3.2.47", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "node_modules/@vue/runtime-core": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz", - "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz", + "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==", "dependencies": { - "@vue/reactivity": "3.2.47", - "@vue/shared": "3.2.47" + "@vue/reactivity": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/@vue/runtime-dom": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz", - "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz", + "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==", "dependencies": { - "@vue/runtime-core": "3.2.47", - "@vue/shared": "3.2.47", + "@vue/runtime-core": "3.2.45", + "@vue/shared": "3.2.45", "csstype": "^2.6.8" } }, "node_modules/@vue/server-renderer": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz", - "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz", + "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==", "dependencies": { - "@vue/compiler-ssr": "3.2.47", - "@vue/shared": "3.2.47" + "@vue/compiler-ssr": "3.2.45", + "@vue/shared": "3.2.45" }, "peerDependencies": { - "vue": "3.2.47" + "vue": "3.2.45" } }, "node_modules/@vue/shared": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz", - "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==" + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz", + "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==" }, "node_modules/@vueuse/core": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz", - "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.6.0.tgz", + "integrity": "sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==", "dependencies": { "@types/web-bluetooth": "^0.0.16", - "@vueuse/metadata": "9.13.0", - "@vueuse/shared": "9.13.0", + "@vueuse/metadata": "9.6.0", + "@vueuse/shared": "9.6.0", "vue-demi": "*" }, "funding": { @@ -358,17 +385,17 @@ } }, "node_modules/@vueuse/metadata": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz", - "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.6.0.tgz", + "integrity": "sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w==", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz", - "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.6.0.tgz", + "integrity": "sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==", "dependencies": { "vue-demi": "*" }, @@ -427,9 +454,9 @@ "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" }, "node_modules/dayjs": { - "version": "1.11.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", - "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", + "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==" }, "node_modules/de-indent": { "version": "1.0.2", @@ -438,9 +465,9 @@ "dev": true }, "node_modules/element-plus": { - "version": "2.2.32", - "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.32.tgz", - "integrity": "sha512-DTJMhYOy6MApbmh6z/95hPTK5WrBiNHGzV4IN+uEkup1WoimQ+Qyt8RxKdTe/X1LWEJ8YgWv/Cl8P4ocrt5z5g==", + "version": "2.2.26", + "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.26.tgz", + "integrity": "sha512-O/rdY5m9DkclpVg8r3GynyqCunm7MxSR142xSsjrZA77bi7bcwA3SIy6SPEDqHi5R4KqgkGYgKSp4Q4e3irbYg==", "dependencies": { "@ctrl/tinycolor": "^3.4.1", "@element-plus/icons-vue": "^2.0.6", @@ -499,463 +526,142 @@ "esbuild-windows-arm64": "0.15.18" } }, - "node_modules/esbuild-android-64": { + "node_modules/esbuild-windows-64": { "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz", - "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz", + "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ - "android" + "win32" ], "engines": { "node": ">=12" } }, - "node_modules/esbuild-android-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz", - "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, - "node_modules/esbuild-darwin-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz", - "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, - "node_modules/esbuild-darwin-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz", - "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, - "node_modules/esbuild-freebsd-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz", - "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==", - "cpu": [ - "x64" - ], + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "function-bind": "^1.1.1" + }, "engines": { - "node": ">=12" + "node": ">= 0.4.0" } }, - "node_modules/esbuild-freebsd-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz", - "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==", - "cpu": [ - "arm64" - ], + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" + "bin": { + "he": "bin/he" } }, - "node_modules/esbuild-linux-32": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz", - "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==", - "cpu": [ - "ia32" - ], + "node_modules/is-core-module": { + "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, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild-linux-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz", - "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/esbuild-linux-arm": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz", - "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, - "node_modules/esbuild-linux-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz", - "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/lodash-unified": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz", + "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" } }, - "node_modules/esbuild-linux-mips64le": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz", - "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" } }, - "node_modules/esbuild-linux-ppc64le": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz", - "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], + "node_modules/marked": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz", + "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==", + "bin": { + "marked": "bin/marked.js" + }, "engines": { - "node": ">=12" + "node": ">= 12" } }, - "node_modules/esbuild-linux-riscv64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz", - "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==", - "cpu": [ - "riscv64" - ], + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "node_modules/minimatch": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.1.tgz", + "integrity": "sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">=12" + "node": ">=10" } }, - "node_modules/esbuild-linux-s390x": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz", - "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], + "node_modules/muggle-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.1.0.tgz", + "integrity": "sha512-Tr1knR3d2mKvvWthlk7202rywKbiOm4rVFLsfAaSIhJ6dt9o47W4S+JMtWhd/PW9Wrdew2/S2fSvhz3E2gkfEg==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-netbsd-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz", - "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-openbsd-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz", - "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-sunos-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz", - "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-32": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz", - "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz", - "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-arm64": { - "version": "0.15.18", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz", - "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/fsevents": { - "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": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/has": { - "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" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/is-core-module": { - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" - }, - "node_modules/lodash-unified": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz", - "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", - "peerDependencies": { - "@types/lodash-es": "*", - "lodash": "*", - "lodash-es": "*" - } - }, - "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/marked": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz", - "integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" - }, - "node_modules/minimatch": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz", - "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/muggle-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.2.2.tgz", - "integrity": "sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/normalize-wheel-es": { @@ -975,9 +681,9 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", + "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", "funding": [ { "type": "opencollective", @@ -1079,9 +785,9 @@ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -1141,15 +847,32 @@ } }, "node_modules/vue": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.47.tgz", - "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz", + "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==", + "dependencies": { + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/runtime-dom": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/vue-i18n": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.2.2.tgz", + "integrity": "sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==", "dependencies": { - "@vue/compiler-dom": "3.2.47", - "@vue/compiler-sfc": "3.2.47", - "@vue/runtime-dom": "3.2.47", - "@vue/server-renderer": "3.2.47", - "@vue/shared": "3.2.47" + "@intlify/core-base": "9.2.2", + "@intlify/shared": "9.2.2", + "@intlify/vue-devtools": "9.2.2", + "@vue/devtools-api": "^6.2.1" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "vue": "^3.0.0" } }, "node_modules/vue-router": { @@ -1177,13 +900,13 @@ } }, "node_modules/vue-tsc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.2.0.tgz", - "integrity": "sha512-rIlzqdrhyPYyLG9zxsVRa+JEseeS9s8F2BbVVVWRRsTZvJO2BbhLEb2HW3MY+DFma0378tnIqs+vfTzbcQtRFw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.0.11.tgz", + "integrity": "sha512-lj+6dEroPsE4wmQOPtjCzAf8x363Km5/tuEvMEoQaoRnzs9myBM46FNvCGIIPStYUGuaqF1W1bORmP2KDQEORA==", "dev": true, "dependencies": { - "@volar/vue-language-core": "1.2.0", - "@volar/vue-typescript": "1.2.0" + "@volar/vue-language-core": "1.0.11", + "@volar/vue-typescript": "1.0.11" }, "bin": { "vue-tsc": "bin/vue-tsc.js" @@ -1203,5 +926,666 @@ "vue": "^3.2.0" } } + }, + "dependencies": { + "@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" + }, + "@ctrl/tinycolor": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", + "integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==" + }, + "@element-plus/icons-vue": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.0.10.tgz", + "integrity": "sha512-ygEZ1mwPjcPo/OulhzLE7mtDrQBWI8vZzEWSNB2W/RNCRjoQGwbaK4N8lV4rid7Ts4qvySU3njMN7YCiSlSaTQ==", + "requires": {} + }, + "@floating-ui/core": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.0.2.tgz", + "integrity": "sha512-Skfy0YS3NJ5nV9us0uuPN0HDk1Q4edljaOhRBJGDWs9EBa7ZVMYBHRFlhLvvmwEoaIM9BlH6QJFn9/uZg0bACg==" + }, + "@floating-ui/dom": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.7.tgz", + "integrity": "sha512-6RsqvCYe0AYWtsGvuWqCm7mZytnXAZCjWtsWu1Kg8dI3INvj/DbKlDsZO+mKSaQdPT12uxIW9W2dAWJkPx4Y5g==", + "requires": { + "@floating-ui/core": "^1.0.2" + } + }, + "@intlify/core-base": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.2.2.tgz", + "integrity": "sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==", + "requires": { + "@intlify/devtools-if": "9.2.2", + "@intlify/message-compiler": "9.2.2", + "@intlify/shared": "9.2.2", + "@intlify/vue-devtools": "9.2.2" + } + }, + "@intlify/devtools-if": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.2.2.tgz", + "integrity": "sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==", + "requires": { + "@intlify/shared": "9.2.2" + } + }, + "@intlify/message-compiler": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.2.2.tgz", + "integrity": "sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==", + "requires": { + "@intlify/shared": "9.2.2", + "source-map": "0.6.1" + } + }, + "@intlify/shared": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz", + "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==" + }, + "@intlify/vue-devtools": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz", + "integrity": "sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==", + "requires": { + "@intlify/core-base": "9.2.2", + "@intlify/shared": "9.2.2" + } + }, + "@popperjs/core": { + "version": "npm:@sxzz/popperjs-es@2.11.7", + "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", + "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==" + }, + "@tauri-apps/api": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.1.0.tgz", + "integrity": "sha512-n13pIqdPd3KtaMmmAcrU7BTfdMtIlGNnfZD0dNX8L4p8dgmuNyikm6JAA+yCpl9gqq6I8x5cV2Y0muqdgD0cWw==" + }, + "@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" + }, + "@types/lodash-es": { + "version": "4.17.6", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.6.tgz", + "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==", + "requires": { + "@types/lodash": "*" + } + }, + "@types/marked": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.7.tgz", + "integrity": "sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw==", + "dev": true + }, + "@types/web-bluetooth": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", + "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" + }, + "@vitejs/plugin-vue": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz", + "integrity": "sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==", + "dev": true, + "requires": {} + }, + "@volar/language-core": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.0.11.tgz", + "integrity": "sha512-YwUYKxIyDc+Fq3kQ6BGGfkrKCG5JzE2Yr6vMxrxEXW2rg/gsq3JgMk/4sI8ybRsaTirhCB4V8+AIVYsvcRxgig==", + "dev": true, + "requires": { + "@volar/source-map": "1.0.11", + "@vue/reactivity": "^3.2.45", + "muggle-string": "^0.1.0" + } + }, + "@volar/source-map": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.0.11.tgz", + "integrity": "sha512-tkuV9MD+OuiZfHA0qZXrPdW6F7TvnpnuTan6Qe7UGUs9+sflezlMJdjaYdGgQObfP+06pcT1E3xdkOoi08ZyyQ==", + "dev": true, + "requires": { + "muggle-string": "^0.1.0" + } + }, + "@volar/typescript": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.0.11.tgz", + "integrity": "sha512-mq7wDDAs0Eb43jev2FxbowuiwWqvL3kb+tar1we8VQbdabpyQ5dmbWPwo/IglevMmW3SKo1Et+6rqAeZpXNnPQ==", + "dev": true, + "requires": { + "@volar/language-core": "1.0.11" + } + }, + "@volar/vue-language-core": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.0.11.tgz", + "integrity": "sha512-A3ODs0/ua7BcpSSnE7KtO8bzWsYsbOJRyW2Q/2uktxlfHj8srln3JdgK/mNlIgfnWtACbE5K+EfMJOgJKv864A==", + "dev": true, + "requires": { + "@volar/language-core": "1.0.11", + "@volar/source-map": "1.0.11", + "@vue/compiler-dom": "^3.2.45", + "@vue/compiler-sfc": "^3.2.45", + "@vue/reactivity": "^3.2.45", + "@vue/shared": "^3.2.45", + "minimatch": "^5.1.0", + "vue-template-compiler": "^2.7.14" + } + }, + "@volar/vue-typescript": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.0.11.tgz", + "integrity": "sha512-jlnFPvBcTyPiAbGlgjhKK7fp3Q+Z7Z5eU1NTbTSS0lQC8Gog3sh2UxLAFG5Voe1gHIxasoOEPXzMR0CWF4bKbA==", + "dev": true, + "requires": { + "@volar/typescript": "1.0.11", + "@volar/vue-language-core": "1.0.11" + } + }, + "@vue/compiler-core": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz", + "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2", + "source-map": "^0.6.1" + } + }, + "@vue/compiler-dom": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz", + "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==", + "requires": { + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@vue/compiler-sfc": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz", + "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-ssr": "3.2.45", + "@vue/reactivity-transform": "3.2.45", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7", + "postcss": "^8.1.10", + "source-map": "^0.6.1" + } + }, + "@vue/compiler-ssr": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz", + "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==", + "requires": { + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@vue/devtools-api": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz", + "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==" + }, + "@vue/reactivity": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz", + "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==", + "requires": { + "@vue/shared": "3.2.45" + } + }, + "@vue/reactivity-transform": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz", + "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7" + } + }, + "@vue/runtime-core": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz", + "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==", + "requires": { + "@vue/reactivity": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@vue/runtime-dom": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz", + "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==", + "requires": { + "@vue/runtime-core": "3.2.45", + "@vue/shared": "3.2.45", + "csstype": "^2.6.8" + } + }, + "@vue/server-renderer": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz", + "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==", + "requires": { + "@vue/compiler-ssr": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@vue/shared": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz", + "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==" + }, + "@vueuse/core": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.6.0.tgz", + "integrity": "sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==", + "requires": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "9.6.0", + "@vueuse/shared": "9.6.0", + "vue-demi": "*" + }, + "dependencies": { + "vue-demi": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", + "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "requires": {} + } + } + }, + "@vueuse/metadata": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.6.0.tgz", + "integrity": "sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w==" + }, + "@vueuse/shared": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.6.0.tgz", + "integrity": "sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==", + "requires": { + "vue-demi": "*" + }, + "dependencies": { + "vue-demi": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", + "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "requires": {} + } + } + }, + "async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "csstype": { + "version": "2.6.21", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", + "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" + }, + "dayjs": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", + "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==" + }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true + }, + "element-plus": { + "version": "2.2.26", + "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.26.tgz", + "integrity": "sha512-O/rdY5m9DkclpVg8r3GynyqCunm7MxSR142xSsjrZA77bi7bcwA3SIy6SPEDqHi5R4KqgkGYgKSp4Q4e3irbYg==", + "requires": { + "@ctrl/tinycolor": "^3.4.1", + "@element-plus/icons-vue": "^2.0.6", + "@floating-ui/dom": "^1.0.1", + "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", + "@types/lodash": "^4.14.182", + "@types/lodash-es": "^4.17.6", + "@vueuse/core": "^9.1.0", + "async-validator": "^4.2.5", + "dayjs": "^1.11.3", + "escape-html": "^1.0.3", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.2", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.2.0" + } + }, + "esbuild": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz", + "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.15.18", + "@esbuild/linux-loong64": "0.15.18", + "esbuild-android-64": "0.15.18", + "esbuild-android-arm64": "0.15.18", + "esbuild-darwin-64": "0.15.18", + "esbuild-darwin-arm64": "0.15.18", + "esbuild-freebsd-64": "0.15.18", + "esbuild-freebsd-arm64": "0.15.18", + "esbuild-linux-32": "0.15.18", + "esbuild-linux-64": "0.15.18", + "esbuild-linux-arm": "0.15.18", + "esbuild-linux-arm64": "0.15.18", + "esbuild-linux-mips64le": "0.15.18", + "esbuild-linux-ppc64le": "0.15.18", + "esbuild-linux-riscv64": "0.15.18", + "esbuild-linux-s390x": "0.15.18", + "esbuild-netbsd-64": "0.15.18", + "esbuild-openbsd-64": "0.15.18", + "esbuild-sunos-64": "0.15.18", + "esbuild-windows-32": "0.15.18", + "esbuild-windows-64": "0.15.18", + "esbuild-windows-arm64": "0.15.18" + } + }, + "esbuild-windows-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz", + "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==", + "dev": true, + "optional": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "has": { + "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" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "is-core-module": { + "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" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "lodash-unified": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz", + "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", + "requires": {} + }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "marked": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz", + "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==" + }, + "memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "minimatch": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.1.tgz", + "integrity": "sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "muggle-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.1.0.tgz", + "integrity": "sha512-Tr1knR3d2mKvvWthlk7202rywKbiOm4rVFLsfAaSIhJ6dt9o47W4S+JMtWhd/PW9Wrdew2/S2fSvhz3E2gkfEg==", + "dev": true + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + }, + "normalize-wheel-es": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", + "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==" + }, + "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==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "postcss": { + "version": "8.4.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", + "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "resolve": { + "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", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "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==" + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "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==", + "dev": true + }, + "tauri-plugin-store-api": { + "version": "git+ssh://git@github.com/tauri-apps/tauri-plugin-store.git#9bd993aa67766596638bbfd91e79a1bf8f632014", + "integrity": "sha512-X0cDDcEVLY2X8qCLISgAjzuBKDn7bJkj4S7LnXbEPFbPRe+NzhmFGHSAdFCuQuPzQYjmrVg18mZx9NAg4GBHag==", + "from": "tauri-plugin-store-api@github:tauri-apps/tauri-plugin-store#9bd993aa67766596638bbfd91e79a1bf8f632014", + "requires": { + "@tauri-apps/api": "1.1.0", + "tslib": "2.4.0" + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "typescript": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "dev": true + }, + "vite": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.5.tgz", + "integrity": "sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==", + "dev": true, + "requires": { + "esbuild": "^0.15.9", + "fsevents": "~2.3.2", + "postcss": "^8.4.18", + "resolve": "^1.22.1", + "rollup": "^2.79.1" + } + }, + "vue": { + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz", + "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==", + "requires": { + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/runtime-dom": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "vue-i18n": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.2.2.tgz", + "integrity": "sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==", + "requires": { + "@intlify/core-base": "9.2.2", + "@intlify/shared": "9.2.2", + "@intlify/vue-devtools": "9.2.2", + "@vue/devtools-api": "^6.2.1" + } + }, + "vue-router": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz", + "integrity": "sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==", + "requires": { + "@vue/devtools-api": "^6.4.5" + } + }, + "vue-template-compiler": { + "version": "2.7.14", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz", + "integrity": "sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==", + "dev": true, + "requires": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "vue-tsc": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.0.11.tgz", + "integrity": "sha512-lj+6dEroPsE4wmQOPtjCzAf8x363Km5/tuEvMEoQaoRnzs9myBM46FNvCGIIPStYUGuaqF1W1bORmP2KDQEORA==", + "dev": true, + "requires": { + "@volar/vue-language-core": "1.0.11", + "@volar/vue-typescript": "1.0.11" + } + }, + "vuex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz", + "integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==", + "requires": { + "@vue/devtools-api": "^6.0.0-beta.11" + } + } } } diff --git a/src-vue/package.json b/src-vue/package.json index 674ca132..04c1904b 100644 --- a/src-vue/package.json +++ b/src-vue/package.json @@ -14,6 +14,7 @@ "marked": "^4.1.1", "tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#9bd993aa67766596638bbfd91e79a1bf8f632014", "vue": "^3.2.37", + "vue-i18n": "^9.2.2", "vue-router": "^4.1.5", "vuex": "^4.0.2" }, diff --git a/src-vue/src/App.vue b/src-vue/src/App.vue index f740bd2f..86a1bb37 100644 --- a/src-vue/src/App.vue +++ b/src-vue/src/App.vue @@ -6,7 +6,8 @@ import ModsView from './views/ModsView.vue'; import SettingsView from './views/SettingsView.vue'; import { appWindow } from '@tauri-apps/api/window'; import { store } from './plugins/store'; -import { invoke, window as tauriWindow } from "@tauri-apps/api"; +import { Store } from 'tauri-plugin-store-api'; +import { invoke } from "@tauri-apps/api"; export default { components: { @@ -19,8 +20,18 @@ export default { data() { return {} }, - mounted: () => { + mounted: async function() { store.commit('initialize'); + + // Initialize interface language + const persistentStore = new Store('flight-core-settings.json'); + let lang: string | null = await persistentStore.get('lang'); + if (lang === null) { + lang = navigator.language.substring(0, 2); + persistentStore.set('lang', lang); + await persistentStore.save(); + } + this.$root!.$i18n.locale = lang; }, methods: { async toggleMaximize() { @@ -56,11 +67,11 @@ export default { id="fc__menu_items" data-tauri-drag-region > - Play - Changelog - Mods - Settings - Dev + {{ $t('menu.play') }} + {{ $t('menu.changelog') }} + {{ $t('menu.mods') }} + {{ $t('menu.settings') }} + {{ $t('menu.dev') }} diff --git a/src-vue/src/components/LanguageSelector.vue b/src-vue/src/components/LanguageSelector.vue new file mode 100644 index 00000000..c09f6c05 --- /dev/null +++ b/src-vue/src/components/LanguageSelector.vue @@ -0,0 +1,47 @@ + + + diff --git a/src-vue/src/components/ModsMenu.vue b/src-vue/src/components/ModsMenu.vue index 9b62fcfa..656c05a6 100644 --- a/src-vue/src/components/ModsMenu.vue +++ b/src-vue/src/components/ModsMenu.vue @@ -7,20 +7,20 @@
Mods
- Local + {{ $t('mods.menu.local') }} - Online + {{ $t('mods.menu.online') }} -
Filter
- +
{{ $t('mods.menu.filter') }}
+ ({ value: key, - label: Object.values(SortOptions)[Object.keys(SortOptions).indexOf(key)] + label: this.$t('mods.menu.sort.' + Object.values(SortOptions)[Object.keys(SortOptions).indexOf(key)]) })); } } diff --git a/src-vue/src/components/PlayButton.vue b/src-vue/src/components/PlayButton.vue index 687f12a4..3efcc9f5 100644 --- a/src-vue/src/components/PlayButton.vue +++ b/src-vue/src/components/PlayButton.vue @@ -18,22 +18,22 @@ export default defineComponent({ }, playButtonLabel(): string { if (this.$store.state.northstar_is_running) { - return "Game is running"; + return this.$t("play.button.northstar_is_running"); } switch(this.$store.state.northstar_state) { case NorthstarState.GAME_NOT_FOUND: - return "Select Titanfall2 game folder"; + return this.$t("play.button.select_game_dir"); case NorthstarState.INSTALL: - return "Install"; + return this.$t("play.button.install"); case NorthstarState.INSTALLING: - return "Installing..." + return this.$t("play.button.installing"); case NorthstarState.MUST_UPDATE: - return "Update"; + return this.$t("play.button.update"); case NorthstarState.UPDATING: - return "Updating..."; + return this.$t("play.button.updating"); case NorthstarState.READY_TO_PLAY: - return "Launch game"; + return this.$t("play.button.ready_to_play"); default: return ""; @@ -57,7 +57,7 @@ export default defineComponent({ options: [ { value: ReleaseCanal.RELEASE_CANDIDATE, - label: 'Northstar release candidate', + label: this.$t('channels.names.NorthstarReleaseCandidate'), }, ] }, diff --git a/src-vue/src/components/ThunderstoreModCard.vue b/src-vue/src/components/ThunderstoreModCard.vue index c9f6768c..b81ed03c 100644 --- a/src-vue/src/components/ThunderstoreModCard.vue +++ b/src-vue/src/components/ThunderstoreModCard.vue @@ -21,7 +21,7 @@
{{ mod.name }}
-
by {{ mod.owner }}
+
{{ $t('mods.card.by') }} {{ mod.owner }}
{{ latestVersion.description }}
@@ -33,7 +33,7 @@ :loading="isBeingInstalled || isBeingUpdated" @click.stop="installMod(mod)" > - {{ modButtonText }} + {{ $t(modButtonText) }}
@@ -51,10 +51,10 @@ @@ -129,15 +129,15 @@ export default defineComponent({ modButtonText(): string { switch (this.modStatus) { case ThunderstoreModStatus.BEING_INSTALLED: - return "Installing..."; + return "mods.card.button.being_installed"; case ThunderstoreModStatus.BEING_UPDATED: - return "Updating..."; + return "mods.card.button.being_updated"; case ThunderstoreModStatus.INSTALLED: - return "Installed"; + return "mods.card.button.installed"; case ThunderstoreModStatus.NOT_INSTALLED: - return "Install"; + return "mods.card.button.install"; case ThunderstoreModStatus.OUTDATED: - return "Update"; + return "mods.card.button.outdated"; } }, @@ -200,11 +200,11 @@ export default defineComponent({ // Show pop-up to confirm delete ElMessageBox.confirm( - 'Delete Thunderstore mod?', - 'Warning', + this.$t('mods.card.remove_dialog_text'), + this.$t('mods.card.remove_dialog_title'), { - confirmButtonText: 'OK', - cancelButtonText: 'Cancel', + confirmButtonText: this.$t('generic.yes'), + cancelButtonText: this.$t('generic.cancel'), type: 'warning', } ) @@ -217,7 +217,7 @@ export default defineComponent({ await invoke("delete_thunderstore_mod", { gameInstall: game_install, thunderstoreModString: this.latestVersion.full_name }) .then((message) => { ElNotification({ - title: `Removed ${mod.name}`, + title: this.$t('mods.card.remove_success', {modName: mod.name}), message: message as string, type: 'success', position: 'bottom-right' @@ -225,7 +225,7 @@ export default defineComponent({ }) .catch((error) => { ElNotification({ - title: 'Error', + title: this.$t('generic.error'), message: error, type: 'error', position: 'bottom-right' @@ -255,7 +255,7 @@ export default defineComponent({ await invoke("install_mod_caller", { gameInstall: game_install, thunderstoreModString: this.latestVersion.full_name }).then((message) => { ElNotification({ - title: `Installed ${mod.name}`, + title: this.$t('mods.card.install_success', {modName: mod.name}), message: message as string, type: 'success', position: 'bottom-right' @@ -263,7 +263,7 @@ export default defineComponent({ }) .catch((error) => { ElNotification({ - title: 'Error', + title: this.$t('generic.error'), message: error, type: 'error', position: 'bottom-right' diff --git a/src-vue/src/i18n/lang/en.ts b/src-vue/src/i18n/lang/en.ts new file mode 100644 index 00000000..14d744f9 --- /dev/null +++ b/src-vue/src/i18n/lang/en.ts @@ -0,0 +1,156 @@ +export default { + menu: { + play: 'Play', + changelog: 'Changelog', + mods: 'Mods', + settings: 'Settings', + dev: 'Dev' + }, + + generic: { + yes: 'Yes', + no: 'No', + error: 'Error', + cancel: 'Cancel', + informationShort: 'Info' + }, + + play: { + button: { + northstar_is_running: 'Game is running', + select_game_dir: 'Select Titanfall2 game folder', + install: 'Install', + installing: 'Installing...', + update: 'Update', + updating: 'Updating...', + ready_to_play: 'Launch game' + }, + + unknown_version: "Unknown version", + see_patch_notes: "see patch notes", + players: "players", + servers: "servers", + unable_to_load_playercount: "Unable to load playercount", + northstar_running: "Northstar is running:", + origin_running: "Origin is running:" + }, + + mods: { + local: { + no_mods: "No mods were found.", + delete_confirm: "Are you sure to delete this mod?", + delete: "Delete", + part_of_ts_mod: "This Northstar mod is part of a Thunderstore mod", + success_deleting: "Success deleting {modName}" + }, + + online: { + no_match: "No matching mod has been found.", + try_another_search: "Try another search!" + }, + + menu: { + local: 'Local', + online: 'Online', + filter: 'Filter', + search: 'Search', + sort_mods: 'Sort mods', + select_categories: 'Select categories', + + sort: { + name_asc: 'By name (A to Z)', + name_desc: 'By name (Z to A)', + date_asc: 'By date (from oldest)', + date_desc: 'By date (from newest)', + most_downloaded: "Most downloaded", + top_rated: "Top rated" + } + }, + + card: { + button: { + being_installed: "Installing...", + being_updated: "Updating...", + installed: "Installed", + install: "Install", + outdated: "Update" + }, + + by: "by", + more_info: "More info", + remove: "Remove mod", + remove_dialog_title: "Warning", + remove_dialog_text: "Delete Thunderstore mod?", + remove_success: "Removed {modName}", + install_success: "Installed {modName}" + } + }, + + settings: { + manage_install: "Manage installation", + choose_folder: "Choose installation folder", + nb_ts_mods_per_page: "Number of Thunderstore mods per page", + nb_ts_mods_per_page_desc1: "This has an impact on display performances when browsing Thunderstore mods.", + nb_ts_mods_per_page_desc2: "Set this value to 0 to disable pagination.", + nb_ts_mods_reset: "Reset to default", + language: 'Language', + language_select: "Select your favorite language", + about: "About:", + flightcore_version: "FlightCore version:", + testing: "Testing:", + enable_test_channels: "Enable testing release channels", + dev_mode_enabled_title: "Watch out!", + dev_mod_enabled_text: "Developer mode enabled.", + + repair: { + title: "Repair", + open_window: "Open repair window", + + window: { + title: "FlightCore repair window", + warning: "This window contains various functionality to repair common issues with Northstar and FlightCore.", + disable_all_but_core: "Disable all but core mods", + force_reinstall_ns: "Force reinstall Northstar", + force_delete_temp_dl: "Force delete temp download folder", + delete_persistent_store: "Delete FlightCore persistent store" + } + } + }, + + notification: { + game_folder: { + new: { + title: "New game folder", + text: "Game folder was successfully updated." + }, + + wrong: { + title: "Wrong folder", + text: "Selected folder is not a valid Titanfall2 install." + }, + + not_found: { + title: "Titanfall2 not found!", + text: "Please manually select install location" + } + }, + + flightcore_outdated: { + title: "FlightCore outdated!", + text: "Please update FlightCore.\nRunning outdated version {oldVersion}.\nNewest is {newVersion}!" + } + }, + + channels: { + release: { + switch: { + text: 'Switched release channel to "{canal}".' + } + }, + + names: { + Northstar: 'Northstar', + NorthstarReleaseCandidate: 'Northstar release candidate' + } + } +}; diff --git a/src-vue/src/i18n/lang/fr.ts b/src-vue/src/i18n/lang/fr.ts new file mode 100644 index 00000000..f1eba0da --- /dev/null +++ b/src-vue/src/i18n/lang/fr.ts @@ -0,0 +1,156 @@ +export default { + menu: { + play: 'Jouer', + changelog: 'Notes', + mods: 'Mods', + settings: 'Paramètres', + dev: 'Dev' + }, + + generic: { + yes: 'Oui', + no: 'Non', + error: 'Erreur', + cancel: 'Annuler', + informationShort: 'Info' + }, + + play: { + button: { + northstar_is_running: "En cours d'utilisation", + select_game_dir: 'Sélectionner le dossier du jeu', + install: 'Installer', + installing: 'Installation...', + update: 'Mettre à jour', + updating: 'Mise à jour...', + ready_to_play: 'Jouer' + }, + + unknown_version: "Version inconnue", + see_patch_notes: "voir les notes de version", + players: "joueurs", + servers: "serveurs", + unable_to_load_playercount: "Impossible de charger les statistiques", + northstar_running: "Northstar est en cours d'exécution :", + origin_running: "Origin est en cours d'exécution :" + }, + + mods: { + local: { + no_mods: "Aucun mod trouvé.", + delete_confirm: "Êtes-vous certain de vouloir supprimer ce mod ?", + delete: "Supprimer", + part_of_ts_mod: "Ce mod Northstar fait partie d'un mod Thunderstore", + success_deleting: "Succès de la suppression de {modName}" + }, + + online: { + no_match: "Aucun mod correspondant n'a été trouvé.", + try_another_search: "Essayez une autre recherche !" + }, + + menu: { + local: 'Local', + online: 'En ligne', + filter: 'Filtrer', + search: 'Chercher', + sort_mods: 'Trier les mods', + select_categories: 'Choisir les catégories', + + sort: { + name_asc: 'Par nom (de A à Z)', + name_desc: 'Par nom (de Z à A)', + date_asc: 'Par date (du plus vieux)', + date_desc: 'Par date (du plus récent)', + most_downloaded: "Plus téléchargés", + top_rated: "Mieux notés" + } + }, + + card: { + button: { + being_installed: "Installation...", + being_updated: "Mise à jour...", + installed: "Installé", + install: "Installer", + outdated: "Mettre à jour" + }, + + by: "par", + more_info: "Plus d'informations", + remove: "Supprimer le mod", + remove_dialog_title: "Attention !", + remove_dialog_text: "Voulez-vous vraiment supprimer ce mod Thunderstore ?", + remove_success: "{modName} supprimé", + install_success: "{modName} installé" + } + }, + + settings: { + manage_install: "Gérer l'installation", + choose_folder: "Choisir le dossier d'installation du jeu", + nb_ts_mods_per_page: "Nombre de mods Thunderstore par page", + nb_ts_mods_per_page_desc1: "Ce paramètre a un impact sur les performances d'affichage des mods Thunderstore.", + nb_ts_mods_per_page_desc2: "Réglez-le sur 0 pour désactiver la pagination.", + nb_ts_mods_reset: "Valeur par défaut", + language: 'Langue', + language_select: "Sélectionnez votre langue", + about: "À propos:", + flightcore_version: "Version de FlightCore :", + testing: "Tests :", + enable_test_channels: "Activer le test de versions de pré-production", + dev_mode_enabled_title: "Attention !", + dev_mod_enabled_text: "Mode développeur activé.", + + repair: { + title: "Dépannage", + open_window: "Ouvrir la fenêtre de dépannage", + + window: { + title: "Fenêtre de dépannage FlightCore", + warning: "Cette fenêtre contient plusieurs fonctionnalité de résolution de problèmes courants avec Northstar et FlightCore.", + disable_all_but_core: "Désactiver tous les mods (sauf ceux de Northstar)", + force_reinstall_ns: "Forcer la réinstallation de Northstar", + force_delete_temp_dl: "Supprimer le dossier de téléchargement temporaire", + delete_persistent_store: "Supprimer l'espace de stockage local de FlightCore" + } + } + }, + + notification: { + game_folder: { + new: { + title: "Nouveau dossier", + text: "Le dossier du jeu a bien été mis à jour." + }, + + wrong: { + title: "Mauvais dossier", + text: "Le dossier sélectionné ne contient pas d'installation de Titanfall2." + }, + + not_found: { + title: "Titanfall2 non trouvé", + text: "Veuillez sélectionner manuellement le dossier du jeu." + } + }, + + flightcore_outdated: { + title: "Mise à jour disponible !", + text: "Veuillez mettre à jour FlightCore.\nVersion actuelle : {oldVersion}.\nNouvelle version : {newVersion}." + } + }, + + channels: { + release: { + switch: { + text: 'Le canal de téléchargement a été réglé sur "{canal}".' + } + }, + + names: { + Northstar: 'Northstar', + NorthstarReleaseCandidate: 'Version de pré-release' + } + } +}; diff --git a/src-vue/src/main.ts b/src-vue/src/main.ts index 57d41865..7ee700da 100644 --- a/src-vue/src/main.ts +++ b/src-vue/src/main.ts @@ -1,4 +1,5 @@ import { createApp } from 'vue' +import { createI18n } from "vue-i18n"; import App from './App.vue' import ElementPlus from "element-plus"; import * as ElementPlusIconsVue from '@element-plus/icons-vue' @@ -10,10 +11,21 @@ import SettingsView from "./views/SettingsView.vue"; import DeveloperView from "./views/DeveloperView.vue"; import RepairView from "./views/RepairView.vue"; import {createRouter, createWebHashHistory} from "vue-router"; +import en from "./i18n/lang/en"; +import fr from "./i18n/lang/fr"; const app = createApp(App); +// internationalization +export const i18n = createI18n({ + locale: 'en', + fallbackLocale: 'en', + messages: { + en, fr + } +}); +app.use(i18n); // styles import 'element-plus/theme-chalk/index.css'; diff --git a/src-vue/src/plugins/store.ts b/src-vue/src/plugins/store.ts index caa46bee..08f9b85f 100644 --- a/src-vue/src/plugins/store.ts +++ b/src-vue/src/plugins/store.ts @@ -16,8 +16,8 @@ import { ReleaseInfo } from "../../../src-tauri/bindings/ReleaseInfo"; import { ThunderstoreMod } from "../../../src-tauri/bindings/ThunderstoreMod"; import { NorthstarMod } from "../../../src-tauri/bindings/NorthstarMod"; import { searchModule } from './modules/search'; +import { i18n } from '../main'; import { pullRequestModule } from './modules/pull_requests'; -import { PullsApiResponseElement } from "../../../src-tauri/bindings/PullsApiResponseElement"; const persistentStore = new Store('flight-core-settings.json'); @@ -123,8 +123,8 @@ export const store = createStore({ if (is_valid_titanfall2_install) { state.game_path = selected; ElNotification({ - title: 'New game folder', - message: "Game folder was successfully updated.", + title: i18n.global.tc('notification.game_folder.new.title'), + message: i18n.global.tc('notification.game_folder.new.text'), type: 'success', position: 'bottom-right' }); @@ -151,8 +151,8 @@ export const store = createStore({ else { // Not valid Titanfall2 install ElNotification({ - title: 'Wrong folder', - message: "Selected folder is not a valid Titanfall2 install.", + title: i18n.global.tc('notification.game_folder.wrong.title'), + message: i18n.global.tc('notification.game_folder.wrong.text'), type: 'error', position: 'bottom-right' }); @@ -224,7 +224,7 @@ export const store = createStore({ .catch((error) => { console.error(error); ElNotification({ - title: 'Error', + title: i18n.global.tc('generic.error'), message: error, type: 'error', position: 'bottom-right' @@ -293,7 +293,7 @@ export const store = createStore({ .catch((error) => { console.error(error); ElNotification({ - title: 'Error', + title: i18n.global.tc('generic.error'), message: error, type: 'error', position: 'bottom-right' @@ -315,8 +315,8 @@ export const store = createStore({ // Display notification to highlight change ElNotification({ - title: `${state.northstar_release_canal}`, - message: `Switched release channel to: "${state.northstar_release_canal}"`, + title: i18n.global.tc(`channels.names.${state.northstar_release_canal}`), + message: i18n.global.tc('channels.release.switch.text', {canal: state.northstar_release_canal}), type: 'success', position: 'bottom-right' }); @@ -394,8 +394,8 @@ async function _initializeApp(state: any) { // Gamepath not found or other error console.error(err); notification_handle = ElNotification({ - title: 'Titanfall2 not found!', - message: "Please manually select install location", + title: i18n.global.tc('notification.game_folder.not_found.title'), + message: i18n.global.tc('notification.game_folder.not_found.text'), type: 'error', position: 'bottom-right', duration: 0 // Duration `0` means the notification will not auto-vanish @@ -437,8 +437,8 @@ async function _checkForFlightCoreUpdates(state: FlightCoreStore) { if (flightcore_is_outdated) { let newest_flightcore_version = await invoke("get_newest_flightcore_version") as FlightCoreVersion; ElNotification({ - title: 'FlightCore outdated!', - message: `Please update FlightCore.\nRunning outdated version ${state.flightcore_version}.\nNewest is ${newest_flightcore_version.tag_name}!`, + title: i18n.global.tc('notification.flightcore_outdated.title'), + message: i18n.global.tc('notification.flightcore_outdated.text', {oldVersion: state.flightcore_version, newVersion: newest_flightcore_version.tag_name}), type: 'warning', position: 'bottom-right', duration: 0 // Duration `0` means the notification will not auto-vanish diff --git a/src-vue/src/utils/SortOptions.d.ts b/src-vue/src/utils/SortOptions.d.ts index 6bdd0a4a..b6f180d2 100644 --- a/src-vue/src/utils/SortOptions.d.ts +++ b/src-vue/src/utils/SortOptions.d.ts @@ -1,8 +1,8 @@ export enum SortOptions { - NAME_ASC = 'By name (A to Z)', - NAME_DESC = 'By name (Z to A)', - DATE_ASC = 'By date (from oldest)', - DATE_DESC = 'By date (from newest)', - MOST_DOWNLOADED = "Most downloaded", - TOP_RATED = "Top rated" + NAME_ASC = 'name_asc', + NAME_DESC = 'name_desc', + DATE_ASC = 'date_asc', + DATE_DESC = 'date_desc', + MOST_DOWNLOADED = 'most_downloaded', + TOP_RATED = 'top_rated' } diff --git a/src-vue/src/views/PlayView.vue b/src-vue/src/views/PlayView.vue index beca6724..57d02904 100644 --- a/src-vue/src/views/PlayView.vue +++ b/src-vue/src/views/PlayView.vue @@ -34,27 +34,27 @@ export default defineComponent({
Northstar
- {{ northstarVersion === '' ? 'Unknown version' : `v${northstarVersion}` }} + {{ northstarVersion === '' ? $t('play.unknown_version') : `v${northstarVersion}` }}
- {{ playerCount }} players, - {{ serverCount }} servers + {{ playerCount }} {{ $t('play.players') }}, + {{ serverCount }} {{ $t('play.servers') }}
- Unable to load playercount + {{ $t('play.unable_to_load_playercount') }}
-
Northstar is running:
+
{{ $t('play.northstar_running') }}
{{ northstarIsRunning }}
-
Origin is running:
+
{{ $t('play.origin_running') }}
{{ $store.state.origin_is_running }}
diff --git a/src-vue/src/views/RepairView.vue b/src-vue/src/views/RepairView.vue index e7cd479a..12224524 100644 --- a/src-vue/src/views/RepairView.vue +++ b/src-vue/src/views/RepairView.vue @@ -1,30 +1,30 @@