diff --git a/README.md b/README.md index b9acc4b..ee27cf1 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,7 @@ Vite

-SecScore 是一款教育积分管理软件,基于 Electron + React + TypeScript 开发,用于管理学生名单、记录加/扣分、查看排行榜与结算历史,并提供权限保护与数据备份。 - +SecScore 是一款教育积分管理软件,基于 Electron + React + TypeScript 开发,用于管理学生名单、记录加/扣分、查看排行榜与结算历史,并提供权限保护与数据备份。 ## 主要功能 @@ -73,9 +72,11 @@ SecScore 是一款教育积分管理软件,基于 Electron + React + TypeScri 4. 点击“确认提交” 快捷理由: + - 可在“快捷理由”下拉框中选择预设理由,一键填充理由内容/分值(优先尊重你当前是否已手动输入分值) 撤销最近记录: + - “最近记录”默认折叠,展开后可对记录点击“撤销” - 撤销会回滚该条记录对学生积分的影响 diff --git a/SecScore-URL-Protocol.md b/SecScore-URL-Protocol.md index 426d0fa..6ea0d13 100644 --- a/SecScore-URL-Protocol.md +++ b/SecScore-URL-Protocol.md @@ -227,4 +227,3 @@ start "" "secscore://leaderboard" ``` 此类扩展只需在主进程的 URL 解析函数中增加相应分支逻辑即可。 - diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..48354a3 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,101 @@ +# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore + +# Built application files +*.apk +*.aar +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ +# Uncomment the following line in case you need and you don't have the release build type files in your app +# release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ + +# Android Profiling +*.hprof + +# Cordova plugins for Capacitor +capacitor-cordova-android-plugins + +# Copied web assets +app/src/main/assets/public + +# Generated Config files +app/src/main/assets/capacitor.config.json +app/src/main/assets/capacitor.plugins.json +app/src/main/res/xml/config.xml diff --git a/android/app/.gitignore b/android/app/.gitignore new file mode 100644 index 0000000..043df80 --- /dev/null +++ b/android/app/.gitignore @@ -0,0 +1,2 @@ +/build/* +!/build/.npmkeep diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..dcf9784 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,54 @@ +apply plugin: 'com.android.application' + +android { + namespace = "com.sectl.secscore" + compileSdk = rootProject.ext.compileSdkVersion + defaultConfig { + applicationId "com.sectl.secscore" + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + aaptOptions { + // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. + // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61 + ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~' + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +repositories { + flatDir{ + dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' + } +} + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" + implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" + implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion" + implementation project(':capacitor-android') + testImplementation "junit:junit:$junitVersion" + androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" + androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" + implementation project(':capacitor-cordova-android-plugins') +} + +apply from: 'capacitor.build.gradle' + +try { + def servicesJSON = file('google-services.json') + if (servicesJSON.text) { + apply plugin: 'com.google.gms.google-services' + } +} catch(Exception e) { + logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work") +} diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java b/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java new file mode 100644 index 0000000..f2c2217 --- /dev/null +++ b/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.getcapacitor.myapp; + +import static org.junit.Assert.*; + +import android.content.Context; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.getcapacitor.app", appContext.getPackageName()); + } +} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b06ddbf --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/java/com/sectl/secscore/MainActivity.java b/android/app/src/main/java/com/sectl/secscore/MainActivity.java new file mode 100644 index 0000000..97b24e1 --- /dev/null +++ b/android/app/src/main/java/com/sectl/secscore/MainActivity.java @@ -0,0 +1,5 @@ +package com.sectl.secscore; + +import com.getcapacitor.BridgeActivity; + +public class MainActivity extends BridgeActivity {} diff --git a/android/app/src/main/res/drawable-land-hdpi/splash.png b/android/app/src/main/res/drawable-land-hdpi/splash.png new file mode 100644 index 0000000..e31573b Binary files /dev/null and b/android/app/src/main/res/drawable-land-hdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-land-mdpi/splash.png b/android/app/src/main/res/drawable-land-mdpi/splash.png new file mode 100644 index 0000000..f7a6492 Binary files /dev/null and b/android/app/src/main/res/drawable-land-mdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-land-xhdpi/splash.png b/android/app/src/main/res/drawable-land-xhdpi/splash.png new file mode 100644 index 0000000..8077255 Binary files /dev/null and b/android/app/src/main/res/drawable-land-xhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-land-xxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxhdpi/splash.png new file mode 100644 index 0000000..14c6c8f Binary files /dev/null and b/android/app/src/main/res/drawable-land-xxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-land-xxxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxxhdpi/splash.png new file mode 100644 index 0000000..244ca25 Binary files /dev/null and b/android/app/src/main/res/drawable-land-xxxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-port-hdpi/splash.png b/android/app/src/main/res/drawable-port-hdpi/splash.png new file mode 100644 index 0000000..74faaa5 Binary files /dev/null and b/android/app/src/main/res/drawable-port-hdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-port-mdpi/splash.png b/android/app/src/main/res/drawable-port-mdpi/splash.png new file mode 100644 index 0000000..e944f4a Binary files /dev/null and b/android/app/src/main/res/drawable-port-mdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-port-xhdpi/splash.png b/android/app/src/main/res/drawable-port-xhdpi/splash.png new file mode 100644 index 0000000..564a82f Binary files /dev/null and b/android/app/src/main/res/drawable-port-xhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-port-xxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxhdpi/splash.png new file mode 100644 index 0000000..bfabe68 Binary files /dev/null and b/android/app/src/main/res/drawable-port-xxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-port-xxxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxxhdpi/splash.png new file mode 100644 index 0000000..6929071 Binary files /dev/null and b/android/app/src/main/res/drawable-port-xxxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..c7bd21d --- /dev/null +++ b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..d5fccc5 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/splash.png b/android/app/src/main/res/drawable/splash.png new file mode 100644 index 0000000..f7a6492 Binary files /dev/null and b/android/app/src/main/res/drawable/splash.png differ diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..b5ad138 --- /dev/null +++ b/android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..c023e50 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..2127973 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..b441f37 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..72905b8 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..8ed0605 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..9502e47 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..4d1e077 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..df0f158 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..853db04 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..6cdf97c Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..2960cbb Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..8e3093a Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..46de6e2 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..d2ea9ab Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..a40d73e Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/android/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..c5d5899 --- /dev/null +++ b/android/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #FFFFFF + \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..8a48c0d --- /dev/null +++ b/android/app/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + + SecScore + SecScore + com.sectl.secscore + com.sectl.secscore + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..be874e5 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/xml/file_paths.xml b/android/app/src/main/res/xml/file_paths.xml new file mode 100644 index 0000000..bd0c4d8 --- /dev/null +++ b/android/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java b/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java new file mode 100644 index 0000000..0297327 --- /dev/null +++ b/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java @@ -0,0 +1,18 @@ +package com.getcapacitor.myapp; + +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..f8f0e43 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,29 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + google() + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:8.13.0' + classpath 'com.google.gms:google-services:4.4.4' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +apply from: "variables.gradle" + +allprojects { + repositories { + google() + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..2e87c52 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,22 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..1b33c55 Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..7705927 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/android/gradlew b/android/gradlew new file mode 100644 index 0000000..23d15a9 --- /dev/null +++ b/android/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat new file mode 100644 index 0000000..db3a6ac --- /dev/null +++ b/android/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..3b4431d --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,5 @@ +include ':app' +include ':capacitor-cordova-android-plugins' +project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') + +apply from: 'capacitor.settings.gradle' \ No newline at end of file diff --git a/android/variables.gradle b/android/variables.gradle new file mode 100644 index 0000000..ee4ba41 --- /dev/null +++ b/android/variables.gradle @@ -0,0 +1,16 @@ +ext { + minSdkVersion = 24 + compileSdkVersion = 36 + targetSdkVersion = 36 + androidxActivityVersion = '1.11.0' + androidxAppCompatVersion = '1.7.1' + androidxCoordinatorLayoutVersion = '1.3.0' + androidxCoreVersion = '1.17.0' + androidxFragmentVersion = '1.8.9' + coreSplashScreenVersion = '1.2.0' + androidxWebkitVersion = '1.14.0' + junitVersion = '4.13.2' + androidxJunitVersion = '1.3.0' + androidxEspressoCoreVersion = '3.7.0' + cordovaAndroidVersion = '14.0.1' +} \ No newline at end of file diff --git a/capacitor.config.ts b/capacitor.config.ts new file mode 100644 index 0000000..0a207f6 --- /dev/null +++ b/capacitor.config.ts @@ -0,0 +1,26 @@ +import type { CapacitorConfig } from '@capacitor/cli' + +const config: CapacitorConfig = { + appId: 'com.sectl.secscore', + appName: 'SecScore', + webDir: 'out', + server: { + androidScheme: 'https' + }, + plugins: { + Preferences: { + group: 'SecScore' + } + }, + android: { + buildOptions: { + keystorePath: undefined, + keystorePassword: undefined, + keystoreAlias: undefined, + keystoreAliasPassword: undefined, + signingType: 'apksigner' + } + } +} + +export default config diff --git a/package.json b/package.json index 6f3204f..0932995 100644 --- a/package.json +++ b/package.json @@ -19,21 +19,33 @@ "build:unpack": "pnpm -s build && electron-builder --dir --publish never", "build:win": "pnpm -s build && electron-builder --win --publish never", "build:mac": "electron-vite build && electron-builder --mac --publish never", - "build:linux": "electron-vite build && electron-builder --linux --publish never" + "build:linux": "electron-vite build && electron-builder --linux --publish never", + "build:mobile": "vite build --config vite.mobile.config.ts", + "cap:sync": "npx cap sync", + "cap:open:android": "npx cap open android", + "mobile:build": "pnpm build:mobile && pnpm cap:sync", + "mobile:android": "pnpm mobile:build && npx cap open android" }, "dependencies": { + "@ant-design/icons": "^6.1.0", + "@capacitor/android": "^8.1.0", + "@capacitor/cli": "^8.1.0", + "@capacitor/core": "^8.1.0", + "@capacitor/preferences": "^8.0.1", "@electron-toolkit/preload": "^3.0.2", "@electron-toolkit/utils": "^4.0.0", + "antd": "^6.3.1", + "antd-mobile": "^5.42.3", "better-sqlite3": "^12.6.0", "chokidar": "^5.0.0", "es-object-atoms": "^1.1.1", "express": "^5.2.1", "mica-electron": "^1.5.16", "os": "^0.1.2", + "pg": "^8.19.0", "pinyin-pro": "^3.27.0", "react-router-dom": "^6.28.0", "reflect-metadata": "^0.2.2", - "tdesign-react": "^1.16.3", "typeorm": "^0.3.27", "uuid": "^13.0.0", "winston": "^3.19.0", @@ -46,6 +58,7 @@ "@electron-toolkit/tsconfig": "^2.0.0", "@types/better-sqlite3": "^7.6.13", "@types/node": "^22.19.1", + "@types/pg": "^8.18.0", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "@types/uuid": "^11.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f70d654..9b2d514 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,33 @@ importers: .: dependencies: + '@ant-design/icons': + specifier: ^6.1.0 + version: 6.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@capacitor/android': + specifier: ^8.1.0 + version: 8.1.0(@capacitor/core@8.1.0) + '@capacitor/cli': + specifier: ^8.1.0 + version: 8.1.0 + '@capacitor/core': + specifier: ^8.1.0 + version: 8.1.0 + '@capacitor/preferences': + specifier: ^8.0.1 + version: 8.0.1(@capacitor/core@8.1.0) '@electron-toolkit/preload': specifier: ^3.0.2 version: 3.0.2(electron@39.2.7) '@electron-toolkit/utils': specifier: ^4.0.0 version: 4.0.0(electron@39.2.7) + antd: + specifier: ^6.3.1 + version: 6.3.1(moment@2.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + antd-mobile: + specifier: ^5.42.3 + version: 5.42.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) better-sqlite3: specifier: ^12.6.0 version: 12.6.0 @@ -30,6 +51,9 @@ importers: specifier: ^1.5.16 version: 1.5.16 os: {specifier: ^0.1.2, version: 0.1.2} + pg: + specifier: ^8.19.0 + version: 8.19.0 pinyin-pro: specifier: ^3.27.0 version: 3.27.0 @@ -39,12 +63,9 @@ importers: reflect-metadata: specifier: ^0.2.2 version: 0.2.2 - tdesign-react: - specifier: ^1.16.3 - version: 1.16.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) typeorm: specifier: ^0.3.27 - version: 0.3.28(better-sqlite3@12.6.0) + version: 0.3.28(better-sqlite3@12.6.0)(pg@8.19.0) uuid: specifier: ^13.0.0 version: 13.0.0 @@ -73,6 +94,9 @@ importers: '@types/node': specifier: ^22.19.1 version: 22.19.5 + '@types/pg': + specifier: ^8.18.0 + version: 8.18.0 '@types/react': specifier: ^19.2.7 version: 19.2.8 @@ -127,6 +151,41 @@ packages: 7zip-bin@5.2.0: resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==} + '@ant-design/colors@8.0.1': + resolution: {integrity: sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==} + + '@ant-design/cssinjs-utils@2.1.1': + resolution: {integrity: sha512-RKxkj5pGFB+FkPJ5NGhoX3DK3xsv0pMltha7Ei1AnY3tILeq38L7tuhaWDPQI/5nlPxOog44wvqpNyyGcUsNMg==} + peerDependencies: + react: '>=18' + react-dom: '>=18' + + '@ant-design/cssinjs@2.1.0': + resolution: {integrity: sha512-eZFrPCnrYrF3XtL7qA4L75P0qA3TtZta8H3Yggy7UYFh8gZgu5bSMNF+v4UVCzGxzYmx8ZvPdgOce0BJ6PsW9g==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@ant-design/fast-color@3.0.1': + resolution: {integrity: sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==} + engines: {node: '>=8.x'} + + '@ant-design/icons-svg@4.4.2': + resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==} + + '@ant-design/icons@6.1.0': + resolution: {integrity: sha512-KrWMu1fIg3w/1F2zfn+JlfNDU8dDqILfA5Tg85iqs1lf8ooyGlbkA+TkwfOKKgqpUmAiRY1PTFpuOU2DAIgSUg==} + engines: {node: '>=8'} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@ant-design/react-slick@2.0.0': + resolution: {integrity: sha512-HMS9sRoEmZey8LsE/Yo6+klhlzU12PisjrVcydW3So7RdklyEd2qehyU6a7Yp+OYN72mgsYs3NFCyP2lCPFVqg==} + peerDependencies: + react: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -204,8 +263,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.26.10': - resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} + '@babel/runtime@7.28.6': + resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': @@ -220,6 +279,24 @@ packages: resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} + '@capacitor/android@8.1.0': + resolution: {integrity: sha512-z0acTPxj5DCy/U2FU7w+GA93oC+wdyKnsOcRg5rutDmSYa8Do1tzYqApKgf+hnuTNPbtrCTHp0Zy1cLiK/4MEw==} + peerDependencies: + '@capacitor/core': ^8.1.0 + + '@capacitor/cli@8.1.0': + resolution: {integrity: sha512-JAzA/ckPgTCjZz6YumBLV2dNCFEVXAuR1oOKLD7AJ4LAI5pF5RtRZrf5FoaxvJVb0S4CouZT5cD+7NwsNJX/nw==} + engines: {node: '>=22.0.0'} + hasBin: true + + '@capacitor/core@8.1.0': + resolution: {integrity: sha512-UfMBMWc1v7J+14AhH03QmeNwV3HZx3qnOWhpwnHfzALEwAwlV/itQOQqcasMQYhOHWL0tiymc5ByaLTn7KKQxw==} + + '@capacitor/preferences@8.0.1': + resolution: {integrity: sha512-T6no3ebi79XJCk91U3Jp/liJUwgBdvHR+s6vhvPkPxSuch7z3zx5Rv1bdWM6sWruNx+pViuEGqZvbfCdyBvcHQ==} + peerDependencies: + '@capacitor/core': '>=8.0.0' + '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} @@ -297,6 +374,12 @@ packages: engines: {node: '>=14.14'} hasBin: true + '@emotion/hash@0.8.0': + resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} + + '@emotion/unitless@0.7.5': + resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} + '@esbuild/aix-ppc64@0.25.12': resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} engines: {node: '>=18'} @@ -647,6 +730,15 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@floating-ui/core@1.7.4': + resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} + + '@floating-ui/dom@1.7.5': + resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -663,6 +755,38 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@ionic/cli-framework-output@2.2.8': + resolution: {integrity: sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==} + engines: {node: '>=16.0.0'} + + '@ionic/utils-array@2.1.6': + resolution: {integrity: sha512-0JZ1Zkp3wURnv8oq6Qt7fMPo5MpjbLoUoa9Bu2Q4PJuSDWM8H8gwF3dQO7VTeUj3/0o1IB1wGkFWZZYgUXZMUg==} + engines: {node: '>=16.0.0'} + + '@ionic/utils-fs@3.1.7': + resolution: {integrity: sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==} + engines: {node: '>=16.0.0'} + + '@ionic/utils-object@2.1.6': + resolution: {integrity: sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==} + engines: {node: '>=16.0.0'} + + '@ionic/utils-process@2.1.12': + resolution: {integrity: sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==} + engines: {node: '>=16.0.0'} + + '@ionic/utils-stream@3.1.7': + resolution: {integrity: sha512-eSELBE7NWNFIHTbTC2jiMvh1ABKGIpGdUIvARsNPMNQhxJB3wpwdiVnoBoTYp+5a6UUIww4Kpg7v6S7iTctH1w==} + engines: {node: '>=16.0.0'} + + '@ionic/utils-subprocess@3.0.1': + resolution: {integrity: sha512-cT4te3AQQPeIM9WCwIg8ohroJ8TjsYaMb2G4ZEgv9YzeDqHZ4JpeIKqG2SoaA3GmVQ3sOfhPM6Ox9sxphV/d1A==} + engines: {node: '>=16.0.0'} + + '@ionic/utils-terminal@2.3.5': + resolution: {integrity: sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==} + engines: {node: '>=16.0.0'} + '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} @@ -719,8 +843,315 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@popperjs/core@2.11.8': - resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@rc-component/async-validator@5.1.0': + resolution: {integrity: sha512-n4HcR5siNUXRX23nDizbZBQPO0ZM/5oTtmKZ6/eqL0L2bo747cklFdZGRN2f+c9qWGICwDzrhW0H7tE9PptdcA==} + engines: {node: '>=14.x'} + + '@rc-component/cascader@1.14.0': + resolution: {integrity: sha512-Ip9356xwZUR2nbW5PRVGif4B/bDve4pLa/N+PGbvBaTnjbvmN4PFMBGQSmlDlzKP1ovxaYMvwF/dI9lXNLT4iQ==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/checkbox@2.0.0': + resolution: {integrity: sha512-3CXGPpAR9gsPKeO2N78HAPOzU30UdemD6HGJoWVJOpa6WleaGB5kzZj3v6bdTZab31YuWgY/RxV3VKPctn0DwQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/collapse@1.2.0': + resolution: {integrity: sha512-ZRYSKSS39qsFx93p26bde7JUZJshsUBEQRlRXPuJYlAiNX0vyYlF5TsAm8JZN3LcF8XvKikdzPbgAtXSbkLUkw==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/color-picker@3.1.1': + resolution: {integrity: sha512-OHaCHLHszCegdXmIq2ZRIZBN/EtpT6Wm8SG/gpzLATHbVKc/avvuKi+zlOuk05FTWvgaMmpxAko44uRJ3M+2pg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/context@2.0.1': + resolution: {integrity: sha512-HyZbYm47s/YqtP6pKXNMjPEMaukyg7P0qVfgMLzr7YiFNMHbK2fKTAGzms9ykfGHSfyf75nBbgWw+hHkp+VImw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/dialog@1.8.4': + resolution: {integrity: sha512-Ay6PM7phkTkquplG8fWfUGFZ2GTLx9diTl4f0d8Eqxd7W1u1KjE9AQooFQHOHnhZf0Ya3z51+5EKCWHmt/dNEw==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/drawer@1.4.2': + resolution: {integrity: sha512-1ib+fZEp6FBu+YvcIktm+nCQ+Q+qIpwpoaJH6opGr4ofh2QMq+qdr5DLC4oCf5qf3pcWX9lUWPYX652k4ini8Q==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/dropdown@1.0.2': + resolution: {integrity: sha512-6PY2ecUSYhDPhkNHHb4wfeAya04WhpmUSKzdR60G+kMNVUCX2vjT/AgTS0Lz0I/K6xrPMJ3enQbwVpeN3sHCgg==} + peerDependencies: + react: '>=16.11.0' + react-dom: '>=16.11.0' + + '@rc-component/form@1.6.2': + resolution: {integrity: sha512-OgIn2RAoaSBqaIgzJf/X6iflIa9LpTozci1lagLBdURDFhGA370v0+T0tXxOi8YShMjTha531sFhwtnrv+EJaQ==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/image@1.6.0': + resolution: {integrity: sha512-tSfn2ZE/oP082g4QIOxeehkmgnXB7R+5AFj/lIFr4k7pEuxHBdyGIq9axoCY9qea8NN0DY6p4IB/F07tLqaT5A==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/input-number@1.6.2': + resolution: {integrity: sha512-Gjcq7meZlCOiWN1t1xCC+7/s85humHVokTBI7PJgTfoyw5OWF74y3e6P8PHX104g9+b54jsodFIzyaj6p8LI9w==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/input@1.1.2': + resolution: {integrity: sha512-Q61IMR47piUBudgixJ30CciKIy9b1H95qe7GgEKOmSJVJXvFRWJllJfQry9tif+MX2cWFXWJf/RXz4kaCeq/Fg==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@rc-component/mentions@1.6.0': + resolution: {integrity: sha512-KIkQNP6habNuTsLhUv0UGEOwG67tlmE7KNIJoQZZNggEZl5lQJTytFDb69sl5CK3TDdISCTjKP3nGEBKgT61CQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/menu@1.2.0': + resolution: {integrity: sha512-VWwDuhvYHSnTGj4n6bV3ISrLACcPAzdPOq3d0BzkeiM5cve8BEYfvkEhNoM0PLzv51jpcejeyrLXeMVIJ+QJlg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/mini-decimal@1.1.0': + resolution: {integrity: sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==} + engines: {node: '>=8.x'} + + '@rc-component/motion@1.3.1': + resolution: {integrity: sha512-Wo1mkd0tCcHtvYvpPOmlYJz546z16qlsiwaygmW7NPJpOZOF9GBjhGzdzZSsC2lEJ1IUkWLF4gMHlRA1aSA+Yw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/mutate-observer@2.0.1': + resolution: {integrity: sha512-AyarjoLU5YlxuValRi+w8JRH2Z84TBbFO2RoGWz9d8bSu0FqT8DtugH3xC3BV7mUwlmROFauyWuXFuq4IFbH+w==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/notification@1.2.0': + resolution: {integrity: sha512-OX3J+zVU7rvoJCikjrfW7qOUp7zlDeFBK2eA3SFbGSkDqo63Sl4Ss8A04kFP+fxHSxMDIS9jYVEZtU1FNCFuBA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/overflow@1.0.0': + resolution: {integrity: sha512-GSlBeoE0XTBi5cf3zl8Qh7Uqhn7v8RrlJ8ajeVpEkNe94HWy5l5BQ0Mwn2TVUq9gdgbfEMUmTX7tJFAg7mz0Rw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/pagination@1.2.0': + resolution: {integrity: sha512-YcpUFE8dMLfSo6OARJlK6DbHHvrxz7pMGPGmC/caZSJJz6HRKHC1RPP001PRHCvG9Z/veD039uOQmazVuLJzlw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/picker@1.9.0': + resolution: {integrity: sha512-OLisdk8AWVCG9goBU1dWzuH5QlBQk8jktmQ6p0/IyBFwdKGwyIZOSjnBYo8hooHiTdl0lU+wGf/OfMtVBw02KQ==} + engines: {node: '>=12.x'} + peerDependencies: + date-fns: '>= 2.x' + dayjs: '>= 1.x' + luxon: '>= 3.x' + moment: '>= 2.x' + react: '>=16.9.0' + react-dom: '>=16.9.0' + peerDependenciesMeta: + date-fns: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + + '@rc-component/portal@2.2.0': + resolution: {integrity: sha512-oc6FlA+uXCMiwArHsJyHcIkX4q6uKyndrPol2eWX8YPkAnztHOPsFIRtmWG4BMlGE5h7YIRE3NiaJ5VS8Lb1QQ==} + engines: {node: '>=12.x'} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/progress@1.0.2': + resolution: {integrity: sha512-WZUnH9eGxH1+xodZKqdrHke59uyGZSWgj5HBM5Kwk5BrTMuAORO7VJ2IP5Qbm9aH3n9x3IcesqHHR0NWPBC7fQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/qrcode@1.1.1': + resolution: {integrity: sha512-LfLGNymzKdUPjXUbRP+xOhIWY4jQ+YMj5MmWAcgcAq1Ij8XP7tRmAXqyuv96XvLUBE/5cA8hLFl9eO1JQMujrA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/rate@1.0.1': + resolution: {integrity: sha512-bkXxeBqDpl5IOC7yL7GcSYjQx9G8H+6kLYQnNZWeBYq2OYIv1MONd6mqKTjnnJYpV0cQIU2z3atdW0j1kttpTw==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/resize-observer@1.1.1': + resolution: {integrity: sha512-NfXXMmiR+SmUuKE1NwJESzEUYUFWIDUn2uXpxCTOLwiRUUakd62DRNFjRJArgzyFW8S5rsL4aX5XlyIXyC/vRA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/segmented@1.3.0': + resolution: {integrity: sha512-5J/bJ01mbDnoA6P/FW8SxUvKn+OgUSTZJPzCNnTBntG50tzoP7DydGhqxp7ggZXZls7me3mc2EQDXakU3iTVFg==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@rc-component/select@1.6.13': + resolution: {integrity: sha512-Rz5tWhicICyKEu3Z9OakYAMHmHgRAvtSG3OHNZILdw1rEo+3wAAbM2cH/kwXq1jTA36etU1te++oZOm94rmzYw==} + engines: {node: '>=8.x'} + peerDependencies: + react: '*' + react-dom: '*' + + '@rc-component/slider@1.0.1': + resolution: {integrity: sha512-uDhEPU1z3WDfCJhaL9jfd2ha/Eqpdfxsn0Zb0Xcq1NGQAman0TWaR37OWp2vVXEOdV2y0njSILTMpTfPV1454g==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/steps@1.2.2': + resolution: {integrity: sha512-/yVIZ00gDYYPHSY0JP+M+s3ZvuXLu2f9rEjQqiUDs7EcYsUYrpJ/1bLj9aI9R7MBR3fu/NGh6RM9u2qGfqp+Nw==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/switch@1.0.3': + resolution: {integrity: sha512-Jgi+EbOBquje/XNdofr7xbJQZPYJP+BlPfR0h+WN4zFkdtB2EWqEfvkXJWeipflwjWip0/17rNbxEAqs8hVHfw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/table@1.9.1': + resolution: {integrity: sha512-FVI5ZS/GdB3BcgexfCYKi3iHhZS3Fr59EtsxORszYGrfpH1eWr33eDNSYkVfLI6tfJ7vftJDd9D5apfFWqkdJg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/tabs@1.7.0': + resolution: {integrity: sha512-J48cs2iBi7Ho3nptBxxIqizEliUC+ExE23faspUQKGQ550vaBlv3aGF8Epv/UB1vFWeoJDTW/dNzgIU0Qj5i/w==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/textarea@1.1.2': + resolution: {integrity: sha512-9rMUEODWZDMovfScIEHXWlVZuPljZ2pd1LKNjslJVitn4SldEzq5vO1CL3yy3Dnib6zZal2r2DPtjy84VVpF6A==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/tooltip@1.4.0': + resolution: {integrity: sha512-8Rx5DCctIlLI4raR0I0xHjVTf1aF48+gKCNeAAo5bmF5VoR5YED+A/XEqzXv9KKqrJDRcd3Wndpxh2hyzrTtSg==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/tour@2.3.0': + resolution: {integrity: sha512-K04K9r32kUC+auBSQfr+Fss4SpSIS9JGe56oq/ALAX0p+i2ylYOI1MgR83yBY7v96eO6ZFXcM/igCQmubps0Ow==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/tree-select@1.8.0': + resolution: {integrity: sha512-iYsPq3nuLYvGqdvFAW+l+I9ASRIOVbMXyA8FGZg2lGym/GwkaWeJGzI4eJ7c9IOEhRj0oyfIN4S92Fl3J05mjQ==} + peerDependencies: + react: '*' + react-dom: '*' + + '@rc-component/tree@1.2.3': + resolution: {integrity: sha512-mG8hF2ogQcKaEpfyxzPvMWqqkptofd7Sf+YiXOpPzuXLTLwNKfLDJtysc1/oybopbnzxNqWh2Vgwi+GYwNIb7w==} + engines: {node: '>=10.x'} + peerDependencies: + react: '*' + react-dom: '*' + + '@rc-component/trigger@3.9.0': + resolution: {integrity: sha512-X8btpwfrT27AgrZVOz4swclhEHTZcqaHeQMXXBgveagOiakTa36uObXbdwerXffgV8G9dH1fAAE0DHtVQs8EHg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/upload@1.1.0': + resolution: {integrity: sha512-LIBV90mAnUE6VK5N4QvForoxZc4XqEYZimcp7fk+lkE4XwHHyJWxpIXQQwMU8hJM+YwBbsoZkGksL1sISWHQxw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/util@1.9.0': + resolution: {integrity: sha512-5uW6AfhIigCWeEQDthTozlxiT4Prn6xYQWeO0xokjcaa186OtwPRHBZJ2o0T0FhbjGhZ3vXdbkv0sx3gAYW7Vg==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/virtual-list@1.0.2': + resolution: {integrity: sha512-uvTol/mH74FYsn5loDGJxo+7kjkO4i+y4j87Re1pxJBs0FaeuMuLRzQRGaXwnMcV1CxpZLi2Z56Rerj2M00fjQ==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@react-spring/animated@9.6.1': + resolution: {integrity: sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/core@9.6.1': + resolution: {integrity: sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/rafz@9.6.1': + resolution: {integrity: sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ==} + + '@react-spring/shared@9.6.1': + resolution: {integrity: sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/types@9.6.1': + resolution: {integrity: sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==} + + '@react-spring/web@9.6.1': + resolution: {integrity: sha512-X2zR6q2Z+FjsWfGAmAXlQaoUHbPmfuCaXpuM6TcwXPpLE1ZD4A1eys/wpXboFQmDkjnrlTmKvpVna1MjWpZ5Hw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 '@remix-run/router@1.23.2': resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} @@ -763,79 +1194,66 @@ packages: resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.55.1': resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.55.1': resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.55.1': resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.55.1': resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.55.1': resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==} cpu: [loong64] os: [linux] - libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.55.1': resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.55.1': resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==} cpu: [ppc64] os: [linux] - libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.55.1': resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.55.1': resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.55.1': resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.55.1': resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.55.1': resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openbsd-x64@4.55.1': resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==} @@ -905,12 +1323,18 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/fs-extra@8.1.5': + resolution: {integrity: sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==} + '@types/fs-extra@9.0.13': resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} '@types/http-cache-semantics@4.0.4': resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/js-cookie@3.0.6': + resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -923,6 +1347,9 @@ packages: '@types/node@22.19.5': resolution: {integrity: sha512-HfF8+mYcHPcPypui3w3mvzuIErlNOh2OAG+BCeBZCEwyiD5ls2SiCwEyT47OELtf7M3nHxBdu0FsmzdKxkN52Q==} + '@types/pg@8.18.0': + resolution: {integrity: sha512-gT+oueVQkqnj6ajGJXblFR4iavIXWsGAFCk3dP4Kki5+a9R4NMt0JARdk6s8cUKcfUoqP5dAtDSLU8xYUTFV+Q==} + '@types/plist@3.0.5': resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} @@ -937,8 +1364,8 @@ packages: '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} - '@types/sortablejs@1.15.9': - resolution: {integrity: sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ==} + '@types/slice-ansi@4.0.0': + resolution: {integrity: sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==} '@types/triple-beam@1.3.5': resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} @@ -947,9 +1374,6 @@ packages: resolution: {integrity: sha512-HVyk8nj2m+jcFRNazzqyVKiZezyhDKrGUA3jlEcg/nZ6Ms+qHwocba1Y/AaVaznJTAM9xpdFSh+ptbNrhOGvZA==} deprecated: This is a stub types definition. uuid provides its own type definitions, so you do not need this installed. - '@types/validator@13.15.10': - resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==} - '@types/verror@1.10.11': resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==} @@ -1015,6 +1439,14 @@ packages: resolution: {integrity: sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@use-gesture/core@10.3.0': + resolution: {integrity: sha512-rh+6MND31zfHcy9VU3dOZCqGY511lvGcfyJenN4cWZe0u1BH6brBpBddLVXhF2r4BMqWbvxfsbL7D287thJU2A==} + + '@use-gesture/react@10.3.0': + resolution: {integrity: sha512-3zc+Ve99z4usVP6l9knYVbVnZgfqhKah7sIG+PS2w+vpig2v2OLct05vs+ZXMzwxdNCMka8B+8WlOo0z6Pn6DA==} + peerDependencies: + react: '>= 16.8.0' + '@vitejs/plugin-react@5.1.2': resolution: {integrity: sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1051,6 +1483,12 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + ahooks@3.9.6: + resolution: {integrity: sha512-Mr7f05swd5SmKlR9SZo5U6M0LsL4ErweLzpdgXjA1JPmnZ78Vr6wzx0jUtvoxrcqGKYnX0Yjc02iEASVxHFPjQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -1079,6 +1517,24 @@ packages: resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} engines: {node: '>=14'} + antd-mobile-icons@0.3.0: + resolution: {integrity: sha512-rqINQpJWZWrva9moCd1Ye695MZYWmqLPE+bY8d2xLRy7iSQwPsinCdZYjpUPp2zL/LnKYSyXxP2ut2A+DC+whQ==} + + antd-mobile-v5-count@1.0.1: + resolution: {integrity: sha512-YGsiEDCPUDz3SzfXi6gLZn/HpeSMW+jgPc4qiYUr1fSopg3hkUie2TnooJdExgfiETHefH3Ggs58He0OVfegLA==} + + antd-mobile@5.42.3: + resolution: {integrity: sha512-HLykA0Cr2am7dgEch/TRUnr4GHgTOM59rA9CVjgBJVVJ8dk2w8uUBz//Bji19sRH2leiUObWY7KQZpsWF+WQeg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + antd@6.3.1: + resolution: {integrity: sha512-8pRjvxitZFyrYAtgwml93Km7fCXjw9IeqlmzpIsusRsmO3eWFVrOMum6+0TsGCtR/WrXVnPwfsgrFg3ChzGCeA==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + app-builder-bin@5.0.0-alpha.12: resolution: {integrity: sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==} @@ -1140,6 +1596,9 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} @@ -1157,6 +1616,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -1168,6 +1631,10 @@ packages: resolution: {integrity: sha512-FXI191x+D6UPWSze5IzZjhz+i9MK9nsuHsmTX9bXVl52k06AfZ2xql0lrgIUuzsMsJ7Vgl5kIptvDgBLIV3ZSQ==} engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} + big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} @@ -1182,12 +1649,20 @@ packages: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + bplist-parser@0.3.2: + resolution: {integrity: sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==} + engines: {node: '>= 5.10.0'} + brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.4: + resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + engines: {node: 18 || 20 || >=22} + browserslist@4.28.1: resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -1307,6 +1782,10 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + codepage@1.15.0: resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} engines: {node: '>=0.8'} @@ -1338,6 +1817,10 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + commander@5.1.0: resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} engines: {node: '>= 6'} @@ -1350,6 +1833,9 @@ packages: resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} engines: {node: '>=0.10.0'} + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1405,9 +1891,6 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} - dayjs@1.11.10: - resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} - dayjs@1.11.19: resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} @@ -1439,6 +1922,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -1450,6 +1937,10 @@ packages: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -1485,9 +1976,6 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} - dom-helpers@5.2.1: - resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} - dotenv-expand@11.0.7: resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} engines: {node: '>=12'} @@ -1545,6 +2033,10 @@ packages: engines: {node: '>= 12.20.55'} hasBin: true + elementtree@0.1.7: + resolution: {integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==} + engines: {node: '>= 0.4.0'} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1900,6 +2392,10 @@ packages: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} hasBin: true + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -1964,9 +2460,6 @@ packages: hermes-parser@0.25.1: resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} - hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - hosted-git-info@4.1.0: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} engines: {node: '>=10'} @@ -2032,10 +2525,18 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + intersection-observer@0.12.2: + resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==} + deprecated: The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019. + ip-address@10.1.0: resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} engines: {node: '>= 12'} @@ -2076,6 +2577,11 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2104,6 +2610,9 @@ packages: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} + is-mobile@5.0.0: + resolution: {integrity: sha512-Tz/yndySvLAEXh+Uk8liFCxOwVH6YutuR74utvOcu7I9Di+DwM0mtdPVZNaVvvBUM2OXxne/NhOs1zAO7riusQ==} + is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -2159,6 +2668,10 @@ packages: resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -2193,6 +2706,10 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2217,6 +2734,9 @@ packages: json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json2mq@0.2.0: + resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -2235,6 +2755,14 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} @@ -2249,9 +2777,6 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash-es@4.17.22: - resolution: {integrity: sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -2277,6 +2802,10 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.2.6: + resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -2347,6 +2876,10 @@ packages: resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} engines: {node: 20 || >=22} + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2393,6 +2926,10 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -2401,9 +2938,6 @@ packages: resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} - mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} @@ -2422,6 +2956,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + nano-memoize@3.0.16: + resolution: {integrity: sha512-JyK96AKVGAwVeMj3MoMhaSXaUNqgMbCRSQB3trUV8tYZfWEzqUBKdK1qJpfuNXgKeHOx1jv/IEYTM659ly7zUA==} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2430,6 +2967,11 @@ packages: napi-build-utils@2.0.0: resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + native-run@2.0.3: + resolution: {integrity: sha512-U1PllBuzW5d1gfan+88L+Hky2eZx+9gv3Pf6rNBxKbORxi7boHzqiA6QFGSnqMem4j0A9tZ08NMIs5+0m/VS1Q==} + engines: {node: '>=16.0.0'} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -2514,6 +3056,10 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2575,6 +3121,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + path-to-regexp@8.3.0: resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} @@ -2585,8 +3135,39 @@ packages: pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + pg-cloudflare@1.3.0: + resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} + + pg-connection-string@2.11.0: + resolution: {integrity: sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.12.0: + resolution: {integrity: sha512-eIJ0DES8BLaziFHW7VgJEBPi5hg3Nyng5iKpYtj3wbcAUV9A1wLgWiY7ajf/f/oO1wfxt83phXPY8Emztg7ITg==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.12.0: + resolution: {integrity: sha512-uOANXNRACNdElMXJ0tPz6RBM0XQ61nONGAwlt8da5zs/iUOOCLBQOHSXnrC6fMsvtjxbOJrZZl5IScGv+7mpbg==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.19.0: + resolution: {integrity: sha512-QIcLGi508BAHkQ3pJNptsFz5WQMlpGbuBGBaIaXsWK8mel2kQ/rThYI+DbgjUvZrIr7MiuEuc9LcChJoEZK1xQ==} + engines: {node: '>= 16.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2610,6 +3191,22 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.1: + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + postject@1.0.0-alpha.6: resolution: {integrity: sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==} engines: {node: '>=14.0.0'} @@ -2645,6 +3242,10 @@ packages: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} engines: {node: '>=10'} + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -2667,9 +3268,6 @@ packages: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} - raf@3.4.1: - resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==} - range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -2678,6 +3276,31 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} + rc-field-form@1.44.0: + resolution: {integrity: sha512-el7w87fyDUsca63Y/s8qJcq9kNkf/J5h+iTdqG5WsSHLH0e6Usl7QuYSmSVzJMgtp40mOVZIY/W/QP9zwrp1FA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-motion@2.9.5: + resolution: {integrity: sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-segmented@2.4.1: + resolution: {integrity: sha512-KUi+JJFdKnumV9iXlm+BJ00O4NdVBp2TEexLCk6bK1x/RH83TvYKQMzIz/7m3UTRPD08RM/8VG/JNjWgWbd4cw==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + rc-util@5.44.4: + resolution: {integrity: sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -2713,12 +3336,6 @@ packages: peerDependencies: react: '>=16.8' - react-transition-group@4.4.5: - resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} - peerDependencies: - react: '>=16.6.0' - react-dom: '>=16.6.0' - react@19.2.3: resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} engines: {node: '>=0.10.0'} @@ -2742,9 +3359,6 @@ packages: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regexp.prototype.flags@1.5.4: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} @@ -2757,6 +3371,9 @@ packages: resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==} engines: {node: '>=12', npm: '>=6'} + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -2784,6 +3401,11 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rimraf@6.1.3: + resolution: {integrity: sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==} + engines: {node: 20 || >=22} + hasBin: true + roarr@2.15.4: resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} engines: {node: '>=8.0'} @@ -2797,6 +3419,9 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} + runes2@1.1.4: + resolution: {integrity: sha512-LNPnEDPOOU4ehF71m5JoQyzT2yxwD6ZreFJ7MxZUAoMKNMY1XrAo60H1CUoX5ncSm0rIuKlqn9JZNRrRkNou2g==} + safe-array-concat@1.1.3: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} @@ -2822,6 +3447,9 @@ packages: sanitize-filename@1.6.3: resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} + sax@1.1.4: + resolution: {integrity: sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==} + sax@1.4.4: resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} engines: {node: '>=11.0.0'} @@ -2829,6 +3457,13 @@ packages: scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + screenfull@5.2.0: + resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} + engines: {node: '>=0.10.0'} + + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} @@ -2918,10 +3553,17 @@ packages: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} engines: {node: '>=10'} + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + slice-ansi@3.0.0: resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} engines: {node: '>=8'} + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -2934,9 +3576,6 @@ packages: resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - sortablejs@1.15.6: - resolution: {integrity: sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2948,6 +3587,10 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} @@ -2966,6 +3609,11 @@ packages: stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + staged-components@1.1.3: + resolution: {integrity: sha512-9EIswzDqjwlEu+ymkV09TTlJfzSbKgEnNteUnZSTxkpMgr5Wx2CzzA9WcMFWBNCldqVPsHVnRGGrApduq2Se5A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + stat-mode@1.0.0: resolution: {integrity: sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==} engines: {node: '>= 6'} @@ -2978,6 +3626,9 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + string-convert@0.2.1: + resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -3024,6 +3675,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + stylis@4.3.6: + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + sumchecker@3.0.1: resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} engines: {node: '>= 8.0'} @@ -3055,17 +3709,9 @@ packages: resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} engines: {node: '>=18'} - tdesign-icons-react@0.6.1: - resolution: {integrity: sha512-O+hfqf2HEDhZC3e7Rr+pkflnYVW1eMtRqcShhmegwWvj097rP910nGzWBGFNbuQEfoueRlCZ0iSacqYF71JeNQ==} - peerDependencies: - react: '>=16.13.1' - react-dom: '>=16.13.1' - - tdesign-react@1.16.3: - resolution: {integrity: sha512-mTG8XzwifTcpaXzDhk9yjHHlrvoiX1XmFFNsB2NfA5ykNRVtAVeNC2zIokOL6mvOCkkmtrsvaDE+klUc3c4wLA==} - peerDependencies: - react: '>=16.13.1' - react-dom: '>=16.13.1' + tar@7.5.9: + resolution: {integrity: sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==} + engines: {node: '>=18'} temp-file@3.4.0: resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} @@ -3077,6 +3723,13 @@ packages: text-hex@1.0.0: resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + throttle-debounce@5.0.2: + resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} + engines: {node: '>=12.22'} + + through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + tiny-async-pool@1.3.0: resolution: {integrity: sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==} @@ -3099,6 +3752,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + triple-beam@1.4.1: resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} engines: {node: '>= 14.0.0'} @@ -3112,9 +3769,6 @@ packages: peerDependencies: typescript: '>=4.8.4' - tslib@2.3.1: - resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -3243,6 +3897,10 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -3252,6 +3910,11 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf8-byte-length@1.0.5: resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} @@ -3266,10 +3929,6 @@ packages: resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} hasBin: true - validator@13.15.26: - resolution: {integrity: sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==} - engines: {node: '>= 0.10'} - vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -3389,10 +4048,22 @@ packages: engines: {node: '>=0.8'} hasBin: true + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + xmlbuilder@15.1.1: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} engines: {node: '>=8.0'} + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -3435,6 +4106,52 @@ snapshots: 7zip-bin@5.2.0: {} + '@ant-design/colors@8.0.1': + dependencies: + '@ant-design/fast-color': 3.0.1 + + '@ant-design/cssinjs-utils@2.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@ant-design/cssinjs': 2.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@babel/runtime': 7.28.6 + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@ant-design/cssinjs@2.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.28.6 + '@emotion/hash': 0.8.0 + '@emotion/unitless': 0.7.5 + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + csstype: 3.2.3 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + stylis: 4.3.6 + + '@ant-design/fast-color@3.0.1': {} + + '@ant-design/icons-svg@4.4.2': {} + + '@ant-design/icons@6.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@ant-design/colors': 8.0.1 + '@ant-design/icons-svg': 4.4.2 + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@ant-design/react-slick@2.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.28.6 + clsx: 2.1.1 + json2mq: 0.2.0 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + throttle-debounce: 5.0.2 + '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -3529,9 +4246,7 @@ snapshots: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - '@babel/runtime@7.26.10': - dependencies: - regenerator-runtime: 0.14.1 + '@babel/runtime@7.28.6': {} '@babel/template@7.27.2': dependencies: @@ -3556,6 +4271,40 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@capacitor/android@8.1.0(@capacitor/core@8.1.0)': + dependencies: + '@capacitor/core': 8.1.0 + + '@capacitor/cli@8.1.0': + dependencies: + '@ionic/cli-framework-output': 2.2.8 + '@ionic/utils-subprocess': 3.0.1 + '@ionic/utils-terminal': 2.3.5 + commander: 12.1.0 + debug: 4.4.3 + env-paths: 2.2.1 + fs-extra: 11.3.3 + kleur: 4.1.5 + native-run: 2.0.3 + open: 8.4.2 + plist: 3.1.0 + prompts: 2.4.2 + rimraf: 6.1.3 + semver: 7.7.3 + tar: 7.5.9 + tslib: 2.8.1 + xml2js: 0.6.2 + transitivePeerDependencies: + - supports-color + + '@capacitor/core@8.1.0': + dependencies: + tslib: 2.8.1 + + '@capacitor/preferences@8.0.1(@capacitor/core@8.1.0)': + dependencies: + '@capacitor/core': 8.1.0 + '@colors/colors@1.6.0': {} '@dabh/diagnostics@2.0.8': @@ -3688,6 +4437,10 @@ snapshots: - supports-color optional: true + '@emotion/hash@0.8.0': {} + + '@emotion/unitless@0.7.5': {} + '@esbuild/aix-ppc64@0.25.12': optional: true @@ -3890,6 +4643,17 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@floating-ui/core@1.7.4': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.5': + dependencies: + '@floating-ui/core': 1.7.4 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/utils@0.2.10': {} + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -3901,6 +4665,82 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@ionic/cli-framework-output@2.2.8': + dependencies: + '@ionic/utils-terminal': 2.3.5 + debug: 4.4.3 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@ionic/utils-array@2.1.6': + dependencies: + debug: 4.4.3 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@ionic/utils-fs@3.1.7': + dependencies: + '@types/fs-extra': 8.1.5 + debug: 4.4.3 + fs-extra: 9.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@ionic/utils-object@2.1.6': + dependencies: + debug: 4.4.3 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@ionic/utils-process@2.1.12': + dependencies: + '@ionic/utils-object': 2.1.6 + '@ionic/utils-terminal': 2.3.5 + debug: 4.4.3 + signal-exit: 3.0.7 + tree-kill: 1.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@ionic/utils-stream@3.1.7': + dependencies: + debug: 4.4.3 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@ionic/utils-subprocess@3.0.1': + dependencies: + '@ionic/utils-array': 2.1.6 + '@ionic/utils-fs': 3.1.7 + '@ionic/utils-process': 2.1.12 + '@ionic/utils-stream': 3.1.7 + '@ionic/utils-terminal': 2.3.5 + cross-spawn: 7.0.6 + debug: 4.4.3 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@ionic/utils-terminal@2.3.5': + dependencies: + '@types/slice-ansi': 4.0.0 + debug: 4.4.3 + signal-exit: 3.0.7 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + tslib: 2.8.1 + untildify: 4.0.0 + wrap-ansi: 7.0.0 + transitivePeerDependencies: + - supports-color + '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.0': @@ -3971,7 +4811,385 @@ snapshots: '@pkgr/core@0.2.9': {} - '@popperjs/core@2.11.8': {} + '@rc-component/async-validator@5.1.0': + dependencies: + '@babel/runtime': 7.28.6 + + '@rc-component/cascader@1.14.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/select': 1.6.13(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/tree': 1.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/checkbox@2.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/collapse@1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.28.6 + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/color-picker@3.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@ant-design/fast-color': 3.0.1 + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/context@2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/dialog@1.8.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/portal': 2.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/drawer@1.4.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/portal': 2.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/dropdown@1.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/trigger': 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/form@1.6.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/async-validator': 5.1.0 + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/image@1.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/portal': 2.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/input-number@1.6.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/mini-decimal': 1.1.0 + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/input@1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/mentions@1.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/input': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/menu': 1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/textarea': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/trigger': 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/menu@1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/overflow': 1.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/trigger': 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/mini-decimal@1.1.0': + dependencies: + '@babel/runtime': 7.28.6 + + '@rc-component/motion@1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/mutate-observer@2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/notification@1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/overflow@1.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.28.6 + '@rc-component/resize-observer': 1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/pagination@1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/picker@1.9.0(dayjs@1.11.19)(moment@2.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/overflow': 1.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/resize-observer': 1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/trigger': 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + dayjs: 1.11.19 + moment: 2.30.1 + + '@rc-component/portal@2.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/progress@1.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/qrcode@1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.28.6 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/rate@1.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/resize-observer@1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/segmented@1.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.28.6 + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/select@1.6.13(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/overflow': 1.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/trigger': 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/virtual-list': 1.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/slider@1.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/steps@1.2.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/switch@1.0.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/table@1.9.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/context': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/resize-observer': 1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/virtual-list': 1.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/tabs@1.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/dropdown': 1.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/menu': 1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/resize-observer': 1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/textarea@1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/input': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/resize-observer': 1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/tooltip@1.4.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/trigger': 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/tour@2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/portal': 2.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/trigger': 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/tree-select@1.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/select': 1.6.13(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/tree': 1.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/tree@1.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/virtual-list': 1.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/trigger@3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/portal': 2.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/resize-observer': 1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/upload@1.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@rc-component/util@1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + is-mobile: 5.0.0 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-is: 18.3.1 + + '@rc-component/virtual-list@1.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@babel/runtime': 7.28.6 + '@rc-component/resize-observer': 1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@react-spring/animated@9.6.1(react@19.2.3)': + dependencies: + '@react-spring/shared': 9.6.1(react@19.2.3) + '@react-spring/types': 9.6.1 + react: 19.2.3 + + '@react-spring/core@9.6.1(react@19.2.3)': + dependencies: + '@react-spring/animated': 9.6.1(react@19.2.3) + '@react-spring/rafz': 9.6.1 + '@react-spring/shared': 9.6.1(react@19.2.3) + '@react-spring/types': 9.6.1 + react: 19.2.3 + + '@react-spring/rafz@9.6.1': {} + + '@react-spring/shared@9.6.1(react@19.2.3)': + dependencies: + '@react-spring/rafz': 9.6.1 + '@react-spring/types': 9.6.1 + react: 19.2.3 + + '@react-spring/types@9.6.1': {} + + '@react-spring/web@9.6.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@react-spring/animated': 9.6.1(react@19.2.3) + '@react-spring/core': 9.6.1(react@19.2.3) + '@react-spring/shared': 9.6.1(react@19.2.3) + '@react-spring/types': 9.6.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) '@remix-run/router@1.23.2': {} @@ -4103,12 +5321,18 @@ snapshots: '@types/estree@1.0.8': {} + '@types/fs-extra@8.1.5': + dependencies: + '@types/node': 22.19.5 + '@types/fs-extra@9.0.13': dependencies: '@types/node': 22.19.5 '@types/http-cache-semantics@4.0.4': {} + '@types/js-cookie@3.0.6': {} + '@types/json-schema@7.0.15': {} '@types/keyv@3.1.4': @@ -4121,6 +5345,12 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/pg@8.18.0': + dependencies: + '@types/node': 22.19.5 + pg-protocol: 1.12.0 + pg-types: 2.2.0 + '@types/plist@3.0.5': dependencies: '@types/node': 22.19.5 @@ -4139,7 +5369,7 @@ snapshots: dependencies: '@types/node': 22.19.5 - '@types/sortablejs@1.15.9': {} + '@types/slice-ansi@4.0.0': {} '@types/triple-beam@1.3.5': {} @@ -4147,8 +5377,6 @@ snapshots: dependencies: uuid: 13.0.0 - '@types/validator@13.15.10': {} - '@types/verror@1.10.11': optional: true @@ -4248,6 +5476,13 @@ snapshots: '@typescript-eslint/types': 8.52.0 eslint-visitor-keys: 4.2.1 + '@use-gesture/core@10.3.0': {} + + '@use-gesture/react@10.3.0(react@19.2.3)': + dependencies: + '@use-gesture/core': 10.3.0 + react: 19.2.3 + '@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@22.19.5)(jiti@2.6.1))': dependencies: '@babel/core': 7.28.5 @@ -4279,6 +5514,21 @@ snapshots: agent-base@7.1.4: {} + ahooks@3.9.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@babel/runtime': 7.28.6 + '@types/js-cookie': 3.0.6 + dayjs: 1.11.19 + intersection-observer: 0.12.2 + js-cookie: 3.0.5 + lodash: 4.17.21 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-fast-compare: 3.2.2 + resize-observer-polyfill: 1.5.1 + screenfull: 5.2.0 + tslib: 2.8.1 + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 @@ -4302,6 +5552,92 @@ snapshots: ansis@4.2.0: {} + antd-mobile-icons@0.3.0: {} + + antd-mobile-v5-count@1.0.1: {} + + antd-mobile@5.42.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@floating-ui/dom': 1.7.5 + '@rc-component/mini-decimal': 1.1.0 + '@react-spring/web': 9.6.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@use-gesture/react': 10.3.0(react@19.2.3) + ahooks: 3.9.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + antd-mobile-icons: 0.3.0 + antd-mobile-v5-count: 1.0.1 + classnames: 2.5.1 + dayjs: 1.11.19 + deepmerge: 4.3.1 + nano-memoize: 3.0.16 + rc-field-form: 1.44.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + rc-segmented: 2.4.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-fast-compare: 3.2.2 + react-is: 18.3.1 + runes2: 1.1.4 + staged-components: 1.1.3(react@19.2.3) + tslib: 2.8.1 + use-sync-external-store: 1.6.0(react@19.2.3) + + antd@6.3.1(moment@2.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@ant-design/colors': 8.0.1 + '@ant-design/cssinjs': 2.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@ant-design/cssinjs-utils': 2.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@ant-design/fast-color': 3.0.1 + '@ant-design/icons': 6.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@ant-design/react-slick': 2.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@babel/runtime': 7.28.6 + '@rc-component/cascader': 1.14.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/checkbox': 2.0.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/collapse': 1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/color-picker': 3.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/dialog': 1.8.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/drawer': 1.4.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/dropdown': 1.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/form': 1.6.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/image': 1.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/input': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/input-number': 1.6.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/mentions': 1.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/menu': 1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/motion': 1.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/mutate-observer': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/notification': 1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/pagination': 1.2.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/picker': 1.9.0(dayjs@1.11.19)(moment@2.30.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/progress': 1.0.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/qrcode': 1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/rate': 1.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/resize-observer': 1.1.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/segmented': 1.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/select': 1.6.13(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/slider': 1.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/steps': 1.2.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/switch': 1.0.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/table': 1.9.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/tabs': 1.7.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/textarea': 1.1.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/tooltip': 1.4.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/tour': 2.3.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/tree': 1.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/tree-select': 1.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/trigger': 3.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/upload': 1.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rc-component/util': 1.9.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + clsx: 2.1.1 + dayjs: 1.11.19 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + scroll-into-view-if-needed: 3.1.0 + throttle-debounce: 5.0.2 + transitivePeerDependencies: + - date-fns + - luxon + - moment + app-builder-bin@5.0.0-alpha.12: {} app-builder-lib@26.4.0(dmg-builder@26.4.0)(electron-builder-squirrel-windows@26.4.0): @@ -4409,13 +5745,14 @@ snapshots: assert-plus@1.0.0: optional: true - astral-regex@2.0.0: - optional: true + astral-regex@2.0.0: {} async-exit-hook@2.0.1: {} async-function@1.0.0: {} + async-validator@4.2.5: {} + async@3.2.6: {} asynckit@0.4.0: {} @@ -4428,6 +5765,8 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base64-js@1.5.1: {} baseline-browser-mapping@2.9.14: {} @@ -4437,6 +5776,8 @@ snapshots: bindings: 1.5.0 prebuild-install: 7.1.3 + big-integer@1.6.52: {} + bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 @@ -4464,6 +5805,10 @@ snapshots: boolean@3.2.0: optional: true + bplist-parser@0.3.2: + dependencies: + big-integer: 1.6.52 + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -4473,6 +5818,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.4: + dependencies: + balanced-match: 4.0.4 + browserslist@4.28.1: dependencies: baseline-browser-mapping: 2.9.14 @@ -4625,6 +5974,8 @@ snapshots: clone@1.0.4: {} + clsx@2.1.1: {} + codepage@1.15.0: {} color-convert@2.0.1: @@ -4652,6 +6003,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 + commander@12.1.0: {} + commander@5.1.0: {} commander@9.5.0: @@ -4659,6 +6012,8 @@ snapshots: compare-version@0.1.2: {} + compute-scroll-into-view@3.1.1: {} + concat-map@0.0.1: {} content-disposition@1.0.1: {} @@ -4710,8 +6065,6 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - dayjs@1.11.10: {} - dayjs@1.11.19: {} debug@4.4.3: @@ -4728,6 +6081,8 @@ snapshots: deep-is@0.1.4: {} + deepmerge@4.3.1: {} + defaults@1.0.4: dependencies: clone: 1.0.4 @@ -4740,6 +6095,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + define-lazy-prop@2.0.0: {} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 @@ -4789,11 +6146,6 @@ snapshots: dependencies: esutils: 2.0.3 - dom-helpers@5.2.1: - dependencies: - '@babel/runtime': 7.26.10 - csstype: 3.2.3 - dotenv-expand@11.0.7: dependencies: dotenv: 16.6.1 @@ -4886,6 +6238,10 @@ snapshots: transitivePeerDependencies: - supports-color + elementtree@0.1.7: + dependencies: + sax: 1.1.4 + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -5433,6 +6789,12 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@13.0.6: + dependencies: + minimatch: 10.2.4 + minipass: 7.1.3 + path-scurry: 2.0.2 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -5507,10 +6869,6 @@ snapshots: dependencies: hermes-estree: 0.25.1 - hoist-non-react-statics@3.3.2: - dependencies: - react-is: 16.13.1 - hosted-git-info@4.1.0: dependencies: lru-cache: 6.0.0 @@ -5580,12 +6938,16 @@ snapshots: ini@1.3.8: {} + ini@4.1.3: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.2 side-channel: 1.1.0 + intersection-observer@0.12.2: {} + ip-address@10.1.0: {} ipaddr.js@1.9.1: {} @@ -5630,6 +6992,8 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-docker@2.2.1: {} + is-extglob@2.1.1: {} is-finalizationregistry@1.1.1: @@ -5654,6 +7018,8 @@ snapshots: is-map@2.0.3: {} + is-mobile@5.0.0: {} + is-negative-zero@2.0.3: {} is-number-object@1.1.1: @@ -5706,6 +7072,10 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + isarray@2.0.5: {} isbinaryfile@4.0.10: {} @@ -5739,6 +7109,8 @@ snapshots: jiti@2.6.1: {} + js-cookie@3.0.5: {} + js-tokens@4.0.0: {} js-yaml@4.1.1: @@ -5756,6 +7128,10 @@ snapshots: json-stringify-safe@5.0.1: optional: true + json2mq@0.2.0: + dependencies: + string-convert: 0.2.1 + json5@2.2.3: {} jsonfile@4.0.0: @@ -5779,6 +7155,10 @@ snapshots: dependencies: json-buffer: 3.0.1 + kleur@3.0.3: {} + + kleur@4.1.5: {} + kuler@2.0.0: {} lazy-val@1.0.5: {} @@ -5792,8 +7172,6 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash-es@4.17.22: {} - lodash.merge@4.6.2: {} lodash@4.17.21: {} @@ -5820,6 +7198,8 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@11.2.6: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -5885,6 +7265,10 @@ snapshots: dependencies: '@isaacs/brace-expansion': 5.0.0 + minimatch@10.2.4: + dependencies: + brace-expansion: 5.0.4 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -5931,6 +7315,8 @@ snapshots: minipass@7.1.2: {} + minipass@7.1.3: {} + minizlib@2.1.2: dependencies: minipass: 3.3.6 @@ -5940,8 +7326,6 @@ snapshots: dependencies: minipass: 7.1.2 - mitt@3.0.1: {} - mkdirp-classic@0.5.3: {} mkdirp@0.5.6: @@ -5954,10 +7338,28 @@ snapshots: ms@2.1.3: {} + nano-memoize@3.0.16: {} + nanoid@3.3.11: {} napi-build-utils@2.0.0: {} + native-run@2.0.3: + dependencies: + '@ionic/utils-fs': 3.1.7 + '@ionic/utils-terminal': 2.3.5 + bplist-parser: 0.3.2 + debug: 4.4.3 + elementtree: 0.1.7 + ini: 4.1.3 + plist: 3.1.0 + split2: 4.2.0 + through2: 4.0.2 + tslib: 2.8.1 + yauzl: 2.10.0 + transitivePeerDependencies: + - supports-color + natural-compare@1.4.0: {} negotiator@1.0.0: {} @@ -6054,6 +7456,12 @@ snapshots: dependencies: mimic-fn: 2.1.0 + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -6116,13 +7524,51 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.2: + dependencies: + lru-cache: 11.2.6 + minipass: 7.1.3 + path-to-regexp@8.3.0: {} pe-library@0.4.1: {} pend@1.2.0: {} - performance-now@2.1.0: {} + pg-cloudflare@1.3.0: + optional: true + + pg-connection-string@2.11.0: {} + + pg-int8@1.0.1: {} + + pg-pool@3.12.0(pg@8.19.0): + dependencies: + pg: 8.19.0 + + pg-protocol@1.12.0: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.1 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.19.0: + dependencies: + pg-connection-string: 2.11.0 + pg-pool: 3.12.0(pg@8.19.0) + pg-protocol: 1.12.0 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.3.0 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 picocolors@1.1.1: {} @@ -6144,6 +7590,16 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postgres-array@2.0.0: {} + + postgres-bytea@1.0.1: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + postject@1.0.0-alpha.6: dependencies: commander: 9.5.0 @@ -6181,6 +7637,11 @@ snapshots: err-code: 2.0.3 retry: 0.12.0 + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -6205,10 +7666,6 @@ snapshots: quick-lru@5.1.1: {} - raf@3.4.1: - dependencies: - performance-now: 2.1.0 - range-parser@1.2.1: {} raw-body@3.0.2: @@ -6218,6 +7675,38 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 + rc-field-form@1.44.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@babel/runtime': 7.28.6 + async-validator: 4.2.5 + rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + rc-motion@2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@babel/runtime': 7.28.6 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + rc-segmented@2.4.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@babel/runtime': 7.28.6 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + rc-util: 5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + rc-util@5.44.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@babel/runtime': 7.28.6 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-is: 18.3.1 + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -6250,15 +7739,6 @@ snapshots: '@remix-run/router': 1.23.2 react: 19.2.3 - react-transition-group@4.4.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.26.10 - dom-helpers: 5.2.1 - loose-envify: 1.4.0 - prop-types: 15.8.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react@19.2.3: {} read-binary-file-arch@1.0.6: @@ -6288,8 +7768,6 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerator-runtime@0.14.1: {} - regexp.prototype.flags@1.5.4: dependencies: call-bind: 1.0.8 @@ -6305,6 +7783,8 @@ snapshots: dependencies: pe-library: 0.4.1 + resize-observer-polyfill@1.5.1: {} + resolve-alpn@1.2.1: {} resolve-from@4.0.0: {} @@ -6330,6 +7810,11 @@ snapshots: dependencies: glob: 7.2.3 + rimraf@6.1.3: + dependencies: + glob: 13.0.6 + package-json-from-dist: 1.0.1 + roarr@2.15.4: dependencies: boolean: 3.2.0 @@ -6381,6 +7866,8 @@ snapshots: transitivePeerDependencies: - supports-color + runes2@1.1.4: {} + safe-array-concat@1.1.3: dependencies: call-bind: 1.0.8 @@ -6410,10 +7897,18 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 + sax@1.1.4: {} + sax@1.4.4: {} scheduler@0.27.0: {} + screenfull@5.2.0: {} + + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + semver-compare@1.0.0: optional: true @@ -6533,6 +8028,8 @@ snapshots: dependencies: semver: 7.7.3 + sisteransi@1.0.5: {} + slice-ansi@3.0.0: dependencies: ansi-styles: 4.3.0 @@ -6540,6 +8037,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 optional: true + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + smart-buffer@4.2.0: {} socks-proxy-agent@8.0.5: @@ -6555,8 +8058,6 @@ snapshots: ip-address: 10.1.0 smart-buffer: 4.2.0 - sortablejs@1.15.6: {} - source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -6566,6 +8067,8 @@ snapshots: source-map@0.6.1: {} + split2@4.2.0: {} + sprintf-js@1.1.3: optional: true @@ -6581,6 +8084,10 @@ snapshots: stack-trace@0.0.10: {} + staged-components@1.1.3(react@19.2.3): + dependencies: + react: 19.2.3 + stat-mode@1.0.0: {} statuses@2.0.2: {} @@ -6590,6 +8097,8 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + string-convert@0.2.1: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -6662,6 +8171,8 @@ snapshots: strip-json-comments@3.1.1: {} + stylis@4.3.6: {} + sumchecker@3.0.1: dependencies: debug: 4.4.3 @@ -6710,34 +8221,13 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 - tdesign-icons-react@0.6.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + tar@7.5.9: dependencies: - '@babel/runtime': 7.26.10 - classnames: 2.5.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - - tdesign-react@1.16.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@babel/runtime': 7.26.10 - '@popperjs/core': 2.11.8 - '@types/sortablejs': 1.15.9 - '@types/validator': 13.15.10 - classnames: 2.5.1 - dayjs: 1.11.10 - hoist-non-react-statics: 3.3.2 - lodash-es: 4.17.22 - mitt: 3.0.1 - raf: 3.4.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-fast-compare: 3.2.2 - react-is: 18.3.1 - react-transition-group: 4.4.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - sortablejs: 1.15.6 - tdesign-icons-react: 0.6.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - tslib: 2.3.1 - validator: 13.15.26 + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 temp-file@3.4.0: dependencies: @@ -6751,6 +8241,12 @@ snapshots: text-hex@1.0.0: {} + throttle-debounce@5.0.2: {} + + through2@4.0.2: + dependencies: + readable-stream: 3.6.2 + tiny-async-pool@1.3.0: dependencies: semver: 5.7.2 @@ -6774,6 +8270,8 @@ snapshots: toidentifier@1.0.1: {} + tree-kill@1.2.2: {} + triple-beam@1.4.1: {} truncate-utf8-bytes@1.0.2: @@ -6784,8 +8282,6 @@ snapshots: dependencies: typescript: 5.9.3 - tslib@2.3.1: {} - tslib@2.8.1: {} tunnel-agent@0.6.0: @@ -6838,7 +8334,7 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typeorm@0.3.28(better-sqlite3@12.6.0): + typeorm@0.3.28(better-sqlite3@12.6.0)(pg@8.19.0): dependencies: '@sqltools/formatter': 1.2.5 ansis: 4.2.0 @@ -6857,6 +8353,7 @@ snapshots: yargs: 17.7.2 optionalDependencies: better-sqlite3: 12.6.0 + pg: 8.19.0 transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -6897,6 +8394,8 @@ snapshots: unpipe@1.0.0: {} + untildify@4.0.0: {} + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: browserslist: 4.28.1 @@ -6907,6 +8406,10 @@ snapshots: dependencies: punycode: 2.3.1 + use-sync-external-store@1.6.0(react@19.2.3): + dependencies: + react: 19.2.3 + utf8-byte-length@1.0.5: {} util-deprecate@1.0.2: {} @@ -6915,8 +8418,6 @@ snapshots: uuid@13.0.0: {} - validator@13.15.26: {} - vary@1.1.2: {} verror@1.10.1: @@ -7050,8 +8551,17 @@ snapshots: wmf: 1.0.2 word: 0.3.0 + xml2js@0.6.2: + dependencies: + sax: 1.4.4 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + xmlbuilder@15.1.1: {} + xtend@4.0.2: {} + y18n@5.0.8: {} yallist@3.1.1: {} diff --git a/src/main/db/DbManager.ts b/src/main/db/DbManager.ts index f41067c..b93166d 100644 --- a/src/main/db/DbManager.ts +++ b/src/main/db/DbManager.ts @@ -17,42 +17,229 @@ declare module '../../shared/kernel' { } } -export class DbManager extends Service { - public readonly dataSource: DataSource +interface PostgreSQLConfig { + host: string + port: number + username: string + password: string + database: string + ssl?: boolean + sslmode?: string + channelBinding?: string +} - constructor(ctx: Context, dbPath: string) { - super(ctx, 'db') - const dbDir = path.dirname(dbPath) - if (!fs.existsSync(dbDir)) { - fs.mkdirSync(dbDir, { recursive: true }) - } - this.dataSource = new DataSource({ - type: 'better-sqlite3', - database: dbPath, - entities: [ - StudentEntity, - ReasonEntity, - ScoreEventEntity, - SettlementEntity, - SettingEntity, - TagEntity, - StudentTagEntity - ], - migrations, - synchronize: false, - logging: false - }) +interface QueueItem { + id: string + operation: () => Promise + resolve: (value: any) => void + reject: (error: Error) => void + timestamp: number +} + +export function parsePostgreSQLConnectionString(connectionString: string): PostgreSQLConfig | null { + if (!connectionString.startsWith('postgresql://')) { + return null } - async initialize() { - if (this.dataSource.isInitialized) return - await this.dataSource.initialize() - await this.dataSource.query('PRAGMA foreign_keys = ON') - await this.dataSource.runMigrations() + try { + const url = new URL(connectionString) + const config: PostgreSQLConfig = { + host: url.hostname, + port: url.port ? parseInt(url.port, 10) : 5432, + username: url.username, + password: decodeURIComponent(url.password || ''), + database: url.pathname.slice(1), + ssl: false + } + + const params = new URLSearchParams(url.search) + if (params.get('sslmode')) { + config.ssl = true + config.sslmode = params.get('sslmode') || 'require' + } + if (params.get('channel_binding')) { + config.channelBinding = params.get('channel_binding') || 'require' + } + + return config + } catch (e) { + console.error('Failed to parse PostgreSQL connection string:', e) + return null + } +} + +export class DbManager extends Service { + private _dataSource: DataSource | null = null + private _isPostgreSQL: boolean = false + private dbPath: string + private operationQueue: QueueItem[] = [] + private isProcessingQueue: boolean = false + private queueIdCounter: number = 0 + + constructor(ctx: Context, dbPath: string, pgConnectionString?: string) { + super(ctx, 'db') + this.dbPath = dbPath + this._isPostgreSQL = !!pgConnectionString + } + + get dataSource(): DataSource { + if (!this._dataSource) { + throw new Error('Database not initialized. Call initialize() first.') + } + return this._dataSource + } + + get isPostgreSQL(): boolean { + return this._isPostgreSQL + } + + private createDataSource(pgConnectionString?: string): DataSource { + const pgConfig = pgConnectionString ? parsePostgreSQLConnectionString(pgConnectionString) : null + + if (pgConfig) { + this._isPostgreSQL = true + return new DataSource({ + type: 'postgres', + host: pgConfig.host, + port: pgConfig.port, + username: pgConfig.username, + password: pgConfig.password, + database: pgConfig.database, + ssl: pgConfig.ssl ? { rejectUnauthorized: false } : false, + extra: { + ssl: pgConfig.ssl ? { rejectUnauthorized: false } : undefined, + sslmode: pgConfig.sslmode, + channelBinding: pgConfig.channelBinding + }, + entities: [ + StudentEntity, + ReasonEntity, + ScoreEventEntity, + SettlementEntity, + SettingEntity, + TagEntity, + StudentTagEntity + ], + migrations, + synchronize: false, + logging: false, + poolSize: 10, + connectTimeoutMS: 30000 + }) + } else { + this._isPostgreSQL = false + const dbDir = path.dirname(this.dbPath) + if (!fs.existsSync(dbDir)) { + fs.mkdirSync(dbDir, { recursive: true }) + } + return new DataSource({ + type: 'better-sqlite3', + database: this.dbPath, + entities: [ + StudentEntity, + ReasonEntity, + ScoreEventEntity, + SettlementEntity, + SettingEntity, + TagEntity, + StudentTagEntity + ], + migrations, + synchronize: false, + logging: false + }) + } + } + + async initialize(pgConnectionString?: string) { + if (this._dataSource?.isInitialized) { + await this.dispose() + } + + this._dataSource = this.createDataSource(pgConnectionString) + await this._dataSource.initialize() + + if (!this._isPostgreSQL) { + await this._dataSource.query('PRAGMA foreign_keys = ON') + } + + await this._dataSource.runMigrations() } async dispose() { - if (!this.dataSource.isInitialized) return - await this.dataSource.destroy() + if (!this._dataSource?.isInitialized) return + await this._dataSource.destroy() + this._dataSource = null + } + + async switchConnection(pgConnectionString?: string): Promise<{ type: 'sqlite' | 'postgresql' }> { + await this.dispose() + await this.initialize(pgConnectionString) + return { type: this._isPostgreSQL ? 'postgresql' : 'sqlite' } + } + + getDatabaseType(): 'sqlite' | 'postgresql' { + return this._isPostgreSQL ? 'postgresql' : 'sqlite' + } + + async enqueueOperation(operation: () => Promise): Promise { + return new Promise((resolve, reject) => { + const item: QueueItem = { + id: `op-${++this.queueIdCounter}`, + operation, + resolve: resolve as (value: any) => void, + reject, + timestamp: Date.now() + } + + this.operationQueue.push(item) + this.processQueue() + }) + } + + private async processQueue() { + if (this.isProcessingQueue || this.operationQueue.length === 0) { + return + } + + this.isProcessingQueue = true + + while (this.operationQueue.length > 0) { + const item = this.operationQueue.shift()! + try { + const result = await item.operation() + item.resolve(result) + } catch (error) { + item.reject(error as Error) + } + } + + this.isProcessingQueue = false + } + + async withQueue(operation: () => Promise): Promise { + if (this._isPostgreSQL) { + return this.enqueueOperation(operation) + } + return operation() + } + + async syncToRemote(): Promise<{ success: boolean; message?: string }> { + if (!this._isPostgreSQL) { + return { success: false, message: '当前不是远程数据库模式' } + } + + if (!this._dataSource?.isInitialized) { + return { success: false, message: '数据库未初始化' } + } + + try { + return await this.enqueueOperation(async () => { + await this._dataSource!.query('SELECT 1') + return { success: true, message: '同步成功' } + }) + } catch (error: any) { + return { success: false, message: error?.message || '同步失败' } + } } } diff --git a/src/main/db/migrations/InitSchema2026011800000.ts b/src/main/db/migrations/InitSchema2026011800000.ts index f928626..67f067c 100644 --- a/src/main/db/migrations/InitSchema2026011800000.ts +++ b/src/main/db/migrations/InitSchema2026011800000.ts @@ -3,17 +3,27 @@ import type { MigrationInterface, QueryRunner } from 'typeorm' export class InitSchema2026011800000 implements MigrationInterface { name = 'InitSchema2026011800000' + private isPostgres(queryRunner: QueryRunner): boolean { + return queryRunner.connection.options.type === 'postgres' + } + async up(queryRunner: QueryRunner): Promise { + const isPg = this.isPostgres(queryRunner) + const pkSerial = isPg ? 'SERIAL PRIMARY KEY' : 'integer PRIMARY KEY AUTOINCREMENT' + const now = isPg ? 'CURRENT_TIMESTAMP' : '(CURRENT_TIMESTAMP)' + const defaultZero = isPg ? 'DEFAULT 0' : 'DEFAULT (0)' + const defaultEmptyArr = isPg ? "DEFAULT '[]'" : "DEFAULT '[]'" + if (!(await queryRunner.hasTable('students'))) { await queryRunner.query(` CREATE TABLE "students" ( - "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" ${pkSerial} NOT NULL, "name" text NOT NULL, - "score" integer NOT NULL DEFAULT (0), + "score" integer NOT NULL ${defaultZero}, "extra_json" text, - "tags" text NOT NULL DEFAULT '[]', - "created_at" text NOT NULL DEFAULT (CURRENT_TIMESTAMP), - "updated_at" text NOT NULL DEFAULT (CURRENT_TIMESTAMP) + "tags" text NOT NULL ${defaultEmptyArr}, + "created_at" text NOT NULL DEFAULT ${now}, + "updated_at" text NOT NULL DEFAULT ${now} ) `) } @@ -21,12 +31,12 @@ export class InitSchema2026011800000 implements MigrationInterface { if (!(await queryRunner.hasTable('reasons'))) { await queryRunner.query(` CREATE TABLE "reasons" ( - "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" ${pkSerial} NOT NULL, "content" text NOT NULL, - "category" text NOT NULL DEFAULT ('其他'), + "category" text NOT NULL DEFAULT '其他', "delta" integer NOT NULL, - "is_system" integer NOT NULL DEFAULT (0), - "updated_at" text NOT NULL DEFAULT (CURRENT_TIMESTAMP), + "is_system" integer NOT NULL ${defaultZero}, + "updated_at" text NOT NULL DEFAULT ${now}, CONSTRAINT "UQ_reasons_content" UNIQUE ("content") ) `) @@ -35,10 +45,10 @@ export class InitSchema2026011800000 implements MigrationInterface { if (!(await queryRunner.hasTable('settlements'))) { await queryRunner.query(` CREATE TABLE "settlements" ( - "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" ${pkSerial} NOT NULL, "start_time" text NOT NULL, "end_time" text NOT NULL, - "created_at" text NOT NULL DEFAULT (CURRENT_TIMESTAMP) + "created_at" text NOT NULL DEFAULT ${now} ) `) } @@ -46,14 +56,14 @@ export class InitSchema2026011800000 implements MigrationInterface { if (!(await queryRunner.hasTable('score_events'))) { await queryRunner.query(` CREATE TABLE "score_events" ( - "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" ${pkSerial} NOT NULL, "uuid" text NOT NULL, "student_name" text NOT NULL, "reason_content" text NOT NULL, "delta" integer NOT NULL, "val_prev" integer NOT NULL, "val_curr" integer NOT NULL, - "event_time" text NOT NULL DEFAULT (CURRENT_TIMESTAMP), + "event_time" text NOT NULL DEFAULT ${now}, "settlement_id" integer, CONSTRAINT "UQ_score_events_uuid" UNIQUE ("uuid") ) @@ -72,23 +82,28 @@ export class InitSchema2026011800000 implements MigrationInterface { `) } - await queryRunner.query(` - INSERT OR IGNORE INTO "reasons" ("content","category","delta","is_system","updated_at") VALUES - ('上课发言','课堂表现',1,1,CURRENT_TIMESTAMP), - ('作业优秀','作业情况',2,1,CURRENT_TIMESTAMP), - ('纪律良好','纪律',1,1,CURRENT_TIMESTAMP), - ('帮助同学','品德',2,1,CURRENT_TIMESTAMP), - ('迟到','纪律',-1,1,CURRENT_TIMESTAMP), - ('未交作业','作业情况',-2,1,CURRENT_TIMESTAMP) - `) + const reasonValues = `('上课发言','课堂表现',1,1,CURRENT_TIMESTAMP),('作业优秀','作业情况',2,1,CURRENT_TIMESTAMP),('纪律良好','纪律',1,1,CURRENT_TIMESTAMP),('帮助同学','品德',2,1,CURRENT_TIMESTAMP),('迟到','纪律',-1,1,CURRENT_TIMESTAMP),('未交作业','作业情况',-2,1,CURRENT_TIMESTAMP)` + + if (isPg) { + await queryRunner.query(` + INSERT INTO "reasons" ("content","category","delta","is_system","updated_at") VALUES + ${reasonValues} + ON CONFLICT DO NOTHING + `) + } else { + await queryRunner.query(` + INSERT OR IGNORE INTO "reasons" ("content","category","delta","is_system","updated_at") VALUES + ${reasonValues} + `) + } if (!(await queryRunner.hasTable('tags'))) { await queryRunner.query(` CREATE TABLE "tags" ( - "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" ${pkSerial} NOT NULL, "name" text NOT NULL UNIQUE, - "created_at" text NOT NULL DEFAULT (CURRENT_TIMESTAMP), - "updated_at" text NOT NULL DEFAULT (CURRENT_TIMESTAMP) + "created_at" text NOT NULL DEFAULT ${now}, + "updated_at" text NOT NULL DEFAULT ${now} ) `) } @@ -96,10 +111,10 @@ export class InitSchema2026011800000 implements MigrationInterface { if (!(await queryRunner.hasTable('student_tags'))) { await queryRunner.query(` CREATE TABLE "student_tags" ( - "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" ${pkSerial} NOT NULL, "student_id" integer NOT NULL, "tag_id" integer NOT NULL, - "created_at" text NOT NULL DEFAULT (CURRENT_TIMESTAMP), + "created_at" text NOT NULL DEFAULT ${now}, FOREIGN KEY ("student_id") REFERENCES "students"("id") ON DELETE CASCADE, FOREIGN KEY ("tag_id") REFERENCES "tags"("id") ON DELETE CASCADE, UNIQUE("student_id", "tag_id") @@ -114,14 +129,18 @@ export class InitSchema2026011800000 implements MigrationInterface { `CREATE INDEX IF NOT EXISTS "IDX_student_tags_tag_id" ON "student_tags" ("tag_id")` ) - await queryRunner.query(` - INSERT OR IGNORE INTO "tags" ("name") VALUES - ('优秀生'), - ('班干部'), - ('勤奋'), - ('活跃'), - ('进步快') - `) + const tagValues = `('优秀生'),('班干部'),('勤奋'),('活跃'),('进步快')` + + if (isPg) { + await queryRunner.query(` + INSERT INTO "tags" ("name") VALUES ${tagValues} + ON CONFLICT DO NOTHING + `) + } else { + await queryRunner.query(` + INSERT OR IGNORE INTO "tags" ("name") VALUES ${tagValues} + `) + } } async down(queryRunner: QueryRunner): Promise { diff --git a/src/main/index.ts b/src/main/index.ts index d01d31d..a049695 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -17,6 +17,7 @@ import { WindowManager, type windowManagerOptions } from './services/WindowManag import { TrayService } from './services/TrayService' import { AutoScoreService } from './services/AutoScoreService' import { FileSystemService } from './services/FileSystemService' +import { DbConnectionService } from './services/DbConnectionService' import { StudentRepository } from './repos/StudentRepository' import { ReasonRepository } from './repos/ReasonRepository' import { EventRepository } from './repos/EventRepository' @@ -50,6 +51,7 @@ type mainAppConfig = { logDir: string themeDir: string dbPath: string + pgConnectionString?: string window: windowManagerOptions } @@ -191,6 +193,8 @@ app.whenReady().then(async () => { : ensureWritableDir(join(appRoot, 'themes'), join(dataRoot, 'themes')) const dbPath = is.dev ? join(process.cwd(), 'db.sqlite') : join(dataRoot, 'db.sqlite') + const pgConnectionString = process.env['PG_CONNECTION_STRING'] || undefined + const config: mainAppConfig = { isDev: is.dev, appRoot, @@ -199,6 +203,7 @@ app.whenReady().then(async () => { configDir, themeDir, dbPath, + pgConnectionString, window: { icon, preloadPath: join(__dirname, '../preload/index.js'), @@ -227,7 +232,10 @@ app.whenReady().then(async () => { LoggerToken, (p) => new LoggerService(p.get(MainContext), config.logDir) ) - services.addSingleton(DbManagerToken, (p) => new DbManager(p.get(MainContext), config.dbPath)) + services.addSingleton( + DbManagerToken, + (p) => new DbManager(p.get(MainContext), config.dbPath, config.pgConnectionString) + ) services.addSingleton(SettingsStoreToken, (p) => new SettingsService(p.get(MainContext))) services.addSingleton(SecurityServiceToken, (p) => new SecurityService(p.get(MainContext))) services.addSingleton( @@ -272,14 +280,37 @@ app.whenReady().then(async () => { (p) => new FileSystemService(p.get(MainContext), config.configDir) ) services.addSingleton(AutoScoreServiceToken, (p) => new AutoScoreService(p.get(MainContext))) + services.addSingleton(DbConnectionService, (p) => new DbConnectionService(p.get(MainContext))) }) .configure(async (_builderContext, appCtx) => { const services = appCtx.services services.get(LoggerToken) + // 先初始化 db(使用默认 SQLite) const db = services.get(DbManagerToken) as DbManager await db.initialize() + // 然后初始化 settings const settings = services.get(SettingsStoreToken) as SettingsService await settings.initialize() + // 检查是否需要切换到 PostgreSQL + const pgConnectionString = settings.getValue('pg_connection_string') + if (pgConnectionString) { + try { + await db.switchConnection(pgConnectionString) + await settings.setValue('pg_connection_status', { + connected: true, + type: 'postgresql' + }) + } catch (e: any) { + console.error('Failed to connect to PostgreSQL:', e) + await settings.setValue('pg_connection_status', { + connected: false, + type: 'postgresql', + error: e?.message || '连接失败' + }) + // 切换回 SQLite + await db.switchConnection(undefined) + } + } services.get(SecurityServiceToken) services.get(PermissionServiceToken) services.get(AuthService) @@ -300,32 +331,7 @@ app.whenReady().then(async () => { services.get(FileSystemServiceToken) const autoScore = services.get(AutoScoreServiceToken) as AutoScoreService await autoScore.initialize?.() - }) - .configure(async (_builderContext, appCtx) => { - const services = appCtx.services - services.get(LoggerToken) - const db = services.get(DbManagerToken) as DbManager - await db.initialize() - const settings = services.get(SettingsStoreToken) as SettingsService - await settings.initialize() - services.get(SecurityServiceToken) - services.get(PermissionServiceToken) - services.get(AuthService) - services.get(DataService) - services.get(StudentRepositoryToken) - services.get(ReasonRepositoryToken) - services.get(EventRepositoryToken) - services.get(SettlementRepositoryToken) - const theme = services.get( - ThemeServiceToken - ) as import('./services/ThemeService').ThemeService - await theme.init() - if (!process.env.HEADLESS) { - services.get(WindowManagerToken) - const tray = services.get(TrayServiceToken) as TrayService - tray.initialize() - } - services.get(FileSystemServiceToken) + services.get(DbConnectionService) }) const host = await builder.build() diff --git a/src/main/repos/EventRepository.ts b/src/main/repos/EventRepository.ts index fc9aacd..a7b59a0 100644 --- a/src/main/repos/EventRepository.ts +++ b/src/main/repos/EventRepository.ts @@ -161,6 +161,10 @@ export class EventRepository extends Service { }) } + private isPostgres(): boolean { + return this.ctx.db.dataSource.options.type === 'postgres' + } + async queryByStudent(studentName: string, startTime: string | null, limit: number) { const repo = this.ctx.db.dataSource.getRepository(ScoreEventEntity) const qb = repo @@ -170,7 +174,11 @@ export class EventRepository extends Service { .orderBy('e.event_time', 'DESC') .limit(limit) if (startTime) { - qb.andWhere('julianday(e.event_time) >= julianday(:startTime)', { startTime }) + if (this.isPostgres()) { + qb.andWhere('e.event_time >= :startTime', { startTime }) + } else { + qb.andWhere('julianday(e.event_time) >= julianday(:startTime)', { startTime }) + } } return await qb.getMany() } @@ -193,15 +201,15 @@ export class EventRepository extends Service { } const startTime = start.toISOString() + const isPg = this.isPostgres() + const joinCondition = isPg + ? 'e.student_name = s.name AND e.settlement_id IS NULL AND e.event_time >= :startTime' + : 'e.student_name = s.name AND e.settlement_id IS NULL AND julianday(e.event_time) >= julianday(:startTime)' + const qb = this.ctx.db.dataSource .getRepository(StudentEntity) .createQueryBuilder('s') - .leftJoin( - ScoreEventEntity, - 'e', - 'e.student_name = s.name AND e.settlement_id IS NULL AND julianday(e.event_time) >= julianday(:startTime)', - { startTime } - ) + .leftJoin(ScoreEventEntity, 'e', joinCondition, { startTime }) .select('s.id', 'id') .addSelect('s.name', 'name') .addSelect('s.score', 'score') diff --git a/src/main/repos/SettlementRepository.ts b/src/main/repos/SettlementRepository.ts index b5dd32d..e710c28 100644 --- a/src/main/repos/SettlementRepository.ts +++ b/src/main/repos/SettlementRepository.ts @@ -3,6 +3,10 @@ import { MainContext } from '../context' import { IsNull } from 'typeorm' import { ScoreEventEntity, SettlementEntity, StudentEntity } from '../db/entities' +function isPostgres(ds: any): boolean { + return ds.options?.type === 'postgres' +} + export interface settlementSummary { id: number start_time: string @@ -64,7 +68,9 @@ export class SettlementRepository extends Service { } async findAll(): Promise { - const qb = this.ctx.db.dataSource + const ds = this.ctx.db.dataSource + const orderBy = isPostgres(ds) ? 's.end_time' : 'julianday(s.end_time)' + const qb = ds .getRepository(SettlementEntity) .createQueryBuilder('s') .select('s.id', 'id') @@ -76,7 +82,7 @@ export class SettlementRepository extends Service { .from(ScoreEventEntity, 'e') .where('e.settlement_id = s.id') }, 'event_count') - .orderBy('julianday(s.end_time)', 'DESC') + .orderBy(orderBy, 'DESC') const rows = await qb.getRawMany() return rows.map((r: any) => ({ @@ -100,10 +106,12 @@ export class SettlementRepository extends Service { const endTime = new Date().toISOString() const settlementsRepo = manager.getRepository(SettlementEntity) + const ds = this.ctx.db.dataSource + const orderBy = isPostgres(ds) ? 's.end_time' : 'julianday(s.end_time)' const lastSettlement = await settlementsRepo .createQueryBuilder('s') .select('s.end_time', 'end_time') - .orderBy('julianday(s.end_time)', 'DESC') + .orderBy(orderBy, 'DESC') .limit(1) .getRawOne<{ end_time?: string }>() diff --git a/src/main/services/DbConnectionService.ts b/src/main/services/DbConnectionService.ts new file mode 100644 index 0000000..fd2fa68 --- /dev/null +++ b/src/main/services/DbConnectionService.ts @@ -0,0 +1,153 @@ +import { Service } from '../../shared/kernel' +import { MainContext } from '../context' +import { DataSource } from 'typeorm' +import { StudentEntity } from '../db/entities/StudentEntity' +import { ReasonEntity } from '../db/entities/ReasonEntity' +import { ScoreEventEntity } from '../db/entities/ScoreEventEntity' +import { SettlementEntity } from '../db/entities/SettlementEntity' +import { SettingEntity } from '../db/entities/SettingEntity' +import { TagEntity } from '../db/entities/TagEntity' +import { StudentTagEntity } from '../db/entities/StudentTagEntity' +import { parsePostgreSQLConnectionString } from '../db/DbManager' + +declare module '../../shared/kernel' { + interface Context { + dbConnection: DbConnectionService + } +} + +export class DbConnectionService extends Service { + private testDataSource: DataSource | null = null + + constructor(ctx: MainContext) { + super(ctx, 'dbConnection') + this.registerIpc() + } + + private get mainCtx() { + return this.ctx as MainContext + } + + private registerIpc() { + this.mainCtx.handle('db:testConnection', async (_event, connectionString: string) => { + const result = await this.testConnection(connectionString) + return { success: true, data: result } + }) + + this.mainCtx.handle('db:switchConnection', async (_event, connectionString: string) => { + try { + const result = await this.switchConnection(connectionString) + return { success: true, data: result } + } catch (error: any) { + return { success: false, message: error?.message || '切换失败' } + } + }) + + this.mainCtx.handle('db:getStatus', async () => { + const status = this.getStatus() + return { success: true, data: status } + }) + + this.mainCtx.handle('db:sync', async () => { + const db = this.mainCtx.db + const result = await db.syncToRemote() + return { success: result.success, data: result } + }) + } + + async testConnection(connectionString: string): Promise<{ success: boolean; error?: string }> { + const config = parsePostgreSQLConnectionString(connectionString) + if (!config) { + return { success: false, error: '无效的 PostgreSQL 连接字符串格式' } + } + + try { + if (this.testDataSource) { + await this.testDataSource.destroy() + } + + this.testDataSource = new DataSource({ + type: 'postgres', + host: config.host, + port: config.port, + username: config.username, + password: config.password, + database: config.database, + ssl: config.ssl ? { rejectUnauthorized: false } : false, + extra: { + ssl: config.ssl ? { rejectUnauthorized: false } : undefined, + sslmode: config.sslmode, + channelBinding: config.channelBinding + }, + entities: [ + StudentEntity, + ReasonEntity, + ScoreEventEntity, + SettlementEntity, + SettingEntity, + TagEntity, + StudentTagEntity + ], + synchronize: false, + logging: false, + connectTimeoutMS: 10000 + }) + + await this.testDataSource.initialize() + await this.testDataSource.destroy() + this.testDataSource = null + + return { success: true } + } catch (error: any) { + if (this.testDataSource) { + try { + await this.testDataSource.destroy() + } catch {} + this.testDataSource = null + } + console.error('PostgreSQL connection test failed:', error) + return { success: false, error: error?.message || '连接失败' } + } + } + + async switchConnection(connectionString: string): Promise<{ type: 'sqlite' | 'postgresql' }> { + if (!connectionString) { + // 切换到 SQLite + const result = await this.mainCtx.db.switchConnection(undefined) + await this.mainCtx.settings.setValue('pg_connection_string', '') + await this.mainCtx.settings.setValue('pg_connection_status', { + connected: true, + type: 'sqlite' + }) + return result + } + + const testResult = await this.testConnection(connectionString) + if (!testResult.success) { + await this.mainCtx.settings.setValue('pg_connection_status', { + connected: false, + type: 'postgresql', + error: testResult.error + }) + throw new Error(testResult.error || '连接测试失败') + } + + // 切换到 PostgreSQL + const result = await this.mainCtx.db.switchConnection(connectionString) + await this.mainCtx.settings.setValue('pg_connection_string', connectionString) + await this.mainCtx.settings.setValue('pg_connection_status', { + connected: true, + type: 'postgresql' + }) + + return result + } + + getStatus(): { type: 'sqlite' | 'postgresql'; connected: boolean; error?: string } { + const status = this.mainCtx.settings.getValue('pg_connection_status') + if (status) { + return status + } + return { type: 'sqlite', connected: true } + } +} diff --git a/src/main/services/SettingsService.ts b/src/main/services/SettingsService.ts index d96a320..6135992 100644 --- a/src/main/services/SettingsService.ts +++ b/src/main/services/SettingsService.ts @@ -93,6 +93,16 @@ export class SettingsService extends Service { kind: 'string', defaultValue: 'light-default', writePermission: 'admin' + }, + pg_connection_string: { + kind: 'string', + defaultValue: '', + writePermission: 'admin' + }, + pg_connection_status: { + kind: 'json', + defaultValue: { connected: false, type: 'sqlite' }, + writePermission: 'admin' } } diff --git a/src/main/services/TrayService.ts b/src/main/services/TrayService.ts index 66ed34c..771a185 100644 --- a/src/main/services/TrayService.ts +++ b/src/main/services/TrayService.ts @@ -29,6 +29,13 @@ export class TrayService extends Service { } }, { type: 'separator' }, + { + label: '重启应用', + click: () => { + this.restartApp() + } + }, + { type: 'separator' }, { label: '关闭应用', click: () => { @@ -55,4 +62,9 @@ export class TrayService extends Service { this.mainCtx.windows.open({ key: 'main', title: 'SecScore', route: '/' }) } } + + private restartApp() { + app.relaunch() + app.quit() + } } diff --git a/src/mobile/App.tsx b/src/mobile/App.tsx new file mode 100644 index 0000000..5cdd99d --- /dev/null +++ b/src/mobile/App.tsx @@ -0,0 +1,131 @@ +import { ConfigProvider, theme as antTheme, Layout, message } from 'antd' +import { HashRouter, Routes, Route, Navigate } from 'react-router-dom' +import { useState, useEffect, createContext, useContext } from 'react' +import { MobileHome } from './pages/Home' +import { MobileScore } from './pages/Score' +import { MobileLeaderboard } from './pages/Leaderboard' +import { MobileSettings } from './pages/Settings' +import { MobileLayout } from './components/Layout' + +interface ThemeContextType { + isDark: boolean + toggleTheme: () => void +} + +const ThemeContext = createContext({ + isDark: false, + toggleTheme: () => {} +}) + +export const useTheme = () => useContext(ThemeContext) + +interface ApiConfig { + baseUrl: string +} + +interface ApiContextType { + api: { + get: (path: string) => Promise + post: (path: string, data?: any) => Promise + put: (path: string, data?: any) => Promise + del: (path: string) => Promise + } + config: ApiConfig + setConfig: (config: ApiConfig) => void +} + +const ApiContext = createContext(null) + +export const useApi = () => { + const ctx = useContext(ApiContext) + if (!ctx) throw new Error('useApi must be used within ApiProvider') + return ctx +} + +function App(): React.JSX.Element { + const [isDark, setIsDark] = useState(false) + const [apiConfig, setApiConfig] = useState({ baseUrl: '' }) + const [messageApi, messageHolder] = message.useMessage() + + useEffect(() => { + const savedTheme = localStorage.getItem('theme') + if (savedTheme === 'dark') setIsDark(true) + + const savedApiUrl = localStorage.getItem('apiUrl') + if (savedApiUrl) setApiConfig({ baseUrl: savedApiUrl }) + }, []) + + useEffect(() => { + document.documentElement.setAttribute('theme-mode', isDark ? 'dark' : 'light') + localStorage.setItem('theme', isDark ? 'dark' : 'light') + }, [isDark]) + + useEffect(() => { + if (apiConfig.baseUrl) { + localStorage.setItem('apiUrl', apiConfig.baseUrl) + } + }, [apiConfig]) + + const toggleTheme = () => setIsDark((prev) => !prev) + + const api = { + get: async (path: string) => { + if (!apiConfig.baseUrl) throw new Error('API URL not configured') + const res = await fetch(`${apiConfig.baseUrl}${path}`) + return res.json() + }, + post: async (path: string, data?: any) => { + if (!apiConfig.baseUrl) throw new Error('API URL not configured') + const res = await fetch(`${apiConfig.baseUrl}${path}`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(data) + }) + return res.json() + }, + put: async (path: string, data?: any) => { + if (!apiConfig.baseUrl) throw new Error('API URL not configured') + const res = await fetch(`${apiConfig.baseUrl}${path}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(data) + }) + return res.json() + }, + del: async (path: string) => { + if (!apiConfig.baseUrl) throw new Error('API URL not configured') + const res = await fetch(`${apiConfig.baseUrl}${path}`, { method: 'DELETE' }) + return res.json() + } + } + + return ( + + {messageHolder} + + + + + }> + } /> + } /> + } /> + } /> + } /> + + + + + + + ) +} + +export default App diff --git a/src/mobile/components/Layout.tsx b/src/mobile/components/Layout.tsx new file mode 100644 index 0000000..b978bc1 --- /dev/null +++ b/src/mobile/components/Layout.tsx @@ -0,0 +1,63 @@ +import { Outlet, useLocation, useNavigate } from 'react-router-dom' +import { Layout, TabBar } from 'antd-mobile' +import { + HomeOutlined, + PlusCircleOutlined, + TrophyOutlined, + SettingOutlined +} from '@ant-design/icons' +import { useTheme } from '../App' +import { Switch } from 'antd' + +const { Content } = Layout + +const tabs = [ + { key: '/', title: '主页', icon: }, + { key: '/score', title: '积分', icon: }, + { key: '/leaderboard', title: '排行', icon: }, + { key: '/settings', title: '设置', icon: } +] + +export function MobileLayout(): React.JSX.Element { + const location = useLocation() + const navigate = useNavigate() + const { isDark, toggleTheme } = useTheme() + + return ( + + + + +
+ navigate(key)} + items={tabs.map((tab) => ({ + key: tab.key, + title: tab.title, + icon: tab.icon + }))} + style={{ + '--color': isDark ? '#999' : '#666', + '--active-color': '#1890ff', + backgroundColor: 'transparent' + }} + /> +
+
+ ) +} diff --git a/src/mobile/index.html b/src/mobile/index.html new file mode 100644 index 0000000..8e4f9f8 --- /dev/null +++ b/src/mobile/index.html @@ -0,0 +1,19 @@ + + + + + + + + + + SecScore - 教育积分管理 + + +
+ + + diff --git a/src/mobile/main.tsx b/src/mobile/main.tsx new file mode 100644 index 0000000..fd81885 --- /dev/null +++ b/src/mobile/main.tsx @@ -0,0 +1,11 @@ +import '../renderer/src/assets/main.css' + +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import App from './App' + +createRoot(document.getElementById('root')!).render( + + + +) diff --git a/src/mobile/pages/Home.tsx b/src/mobile/pages/Home.tsx new file mode 100644 index 0000000..e1f1840 --- /dev/null +++ b/src/mobile/pages/Home.tsx @@ -0,0 +1,122 @@ +import { useState, useEffect } from 'react' +import { Card, Tag, SearchBar, Space, SpinLoading } from 'antd-mobile' +import { useApi } from '../App' + +interface Student { + id: number + name: string + score: number +} + +export function MobileHome(): React.JSX.Element { + const { api, config } = useApi() + const [students, setStudents] = useState([]) + const [loading, setLoading] = useState(false) + const [search, setSearch] = useState('') + + useEffect(() => { + if (!config.baseUrl) return + loadStudents() + }, [config.baseUrl]) + + const loadStudents = async () => { + setLoading(true) + try { + const res = await api.get('/api/students') + if (res.success) { + setStudents(res.data || []) + } + } catch (e) { + console.error('Failed to load students:', e) + } finally { + setLoading(false) + } + } + + const filteredStudents = students.filter((s) => + s.name.toLowerCase().includes(search.toLowerCase()) + ) + + const getAvatarColor = (name: string) => { + const colors = [ + '#FF6B6B', + '#4ECDC4', + '#45B7D1', + '#FFA07A', + '#98D8C8', + '#F7DC6F', + '#BB8FCE', + '#85C1E2' + ] + let hash = 0 + for (let i = 0; i < name.length; i++) { + hash = name.charCodeAt(i) + ((hash << 5) - hash) + } + return colors[Math.abs(hash) % colors.length] + } + + if (!config.baseUrl) { + return ( +
+

请先在设置中配置服务器地址

+
+ ) + } + + return ( +
+

学生积分

+ + + + {loading ? ( +
+ +
+ ) : ( + + {filteredStudents.map((student) => ( + +
+
+ {student.name.slice(-2)} +
+
+
{student.name}
+ 0 ? 'success' : student.score < 0 ? 'danger' : 'default'} + > + {student.score > 0 ? `+${student.score}` : student.score} + +
+
+
+ ))} +
+ )} + + {!loading && filteredStudents.length === 0 && ( +
+ {search ? '未找到匹配的学生' : '暂无学生数据'} +
+ )} +
+ ) +} diff --git a/src/mobile/pages/Leaderboard.tsx b/src/mobile/pages/Leaderboard.tsx new file mode 100644 index 0000000..45b9545 --- /dev/null +++ b/src/mobile/pages/Leaderboard.tsx @@ -0,0 +1,104 @@ +import { useState, useEffect } from 'react' +import { Card, SpinLoading, Selector } from 'antd-mobile' +import { useApi } from '../App' + +interface RankRow { + name: string + score: number + range_change: number +} + +export function MobileLeaderboard(): React.JSX.Element { + const { api, config } = useApi() + const [data, setData] = useState([]) + const [loading, setLoading] = useState(false) + const [range, setRange] = useState<'today' | 'week' | 'month'>('today') + + useEffect(() => { + if (!config.baseUrl) return + loadData() + }, [config.baseUrl, range]) + + const loadData = async () => { + setLoading(true) + try { + const res = await api.get(`/api/leaderboard?range=${range}`) + if (res.success) { + setData(res.data?.rows || []) + } + } catch (e) { + console.error('Failed to load leaderboard:', e) + } finally { + setLoading(false) + } + } + + if (!config.baseUrl) { + return ( +
+

请先在设置中配置服务器地址

+
+ ) + } + + return ( +
+

排行榜

+ + setRange(v[0] as 'today' | 'week' | 'month')} + options={[ + { label: '今天', value: 'today' }, + { label: '本周', value: 'week' }, + { label: '本月', value: 'month' } + ]} + style={{ marginBottom: '12px' }} + /> + + {loading ? ( +
+ +
+ ) : ( + + {data.map((row, index) => ( +
+
+ {index + 1} +
+
{row.name}
+
{row.score}
+
0 ? '#52c41a' : row.range_change < 0 ? '#ff4d4f' : '#999' + }} + > + {row.range_change > 0 ? `+${row.range_change}` : row.range_change} +
+
+ ))} + {data.length === 0 && ( +
暂无数据
+ )} +
+ )} +
+ ) +} diff --git a/src/mobile/pages/Score.tsx b/src/mobile/pages/Score.tsx new file mode 100644 index 0000000..12aca72 --- /dev/null +++ b/src/mobile/pages/Score.tsx @@ -0,0 +1,165 @@ +import { useState, useEffect } from 'react' +import { Card, Button, Selector, Input, TextArea, SpinLoading, Toast } from 'antd-mobile' +import { useApi } from '../App' + +interface Student { + id: number + name: string + score: number +} + +interface Reason { + id: number + content: string + delta: number + category: string +} + +export function MobileScore(): React.JSX.Element { + const { api, config } = useApi() + const [students, setStudents] = useState([]) + const [reasons, setReasons] = useState([]) + const [loading, setLoading] = useState(false) + const [submitting, setSubmitting] = useState(false) + const [selectedStudents, setSelectedStudents] = useState([]) + const [selectedReason, setSelectedReason] = useState(null) + const [customScore, setCustomScore] = useState('') + const [customReason, setCustomReason] = useState('') + + useEffect(() => { + if (!config.baseUrl) return + loadData() + }, [config.baseUrl]) + + const loadData = async () => { + setLoading(true) + try { + const [stuRes, reaRes] = await Promise.all([ + api.get('/api/students'), + api.get('/api/reasons') + ]) + if (stuRes.success) setStudents(stuRes.data || []) + if (reaRes.success) setReasons(reaRes.data || []) + } catch (e) { + console.error('Failed to load data:', e) + } finally { + setLoading(false) + } + } + + const handleSubmit = async () => { + if (selectedStudents.length === 0) { + Toast.show({ content: '请选择学生', icon: 'fail' }) + return + } + + const delta = selectedReason?.delta ?? parseInt(customScore, 10) + if (isNaN(delta)) { + Toast.show({ content: '请选择理由或输入分值', icon: 'fail' }) + return + } + + const reasonContent = selectedReason?.content || customReason || '积分变更' + + setSubmitting(true) + try { + let successCount = 0 + for (const studentName of selectedStudents) { + const res = await api.post('/api/events', { + student_name: studentName, + reason_content: reasonContent, + delta + }) + if (res.success) successCount++ + } + + Toast.show({ + content: `已为 ${successCount} 名学生提交积分`, + icon: 'success' + }) + + setSelectedStudents([]) + setSelectedReason(null) + setCustomScore('') + setCustomReason('') + } catch (e) { + Toast.show({ content: '提交失败', icon: 'fail' }) + } finally { + setSubmitting(false) + } + } + + if (!config.baseUrl) { + return ( +
+

请先在设置中配置服务器地址

+
+ ) + } + + return ( +
+

积分操作

+ + {loading ? ( +
+ +
+ ) : ( + <> + + setSelectedStudents(v as string[])} + options={students.map((s) => ({ + label: s.name, + value: s.name + }))} + /> + + + + { + const reason = reasons.find((r) => r.id === v[0]) + setSelectedReason(reason || null) + if (reason) { + setCustomScore(String(Math.abs(reason.delta))) + } + }} + options={reasons.map((r) => ({ + label: `${r.content} (${r.delta > 0 ? `+${r.delta}` : r.delta})`, + value: r.id + }))} + /> + + + +
+ +