├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src └── main ├── java └── com │ └── fjut │ └── noveltts │ ├── NovelTtsApplication.java │ ├── config │ └── MvcConfigurer.java │ ├── controller │ └── HandleController.java │ ├── entity │ ├── ArticleData.java │ ├── SentenceInfo.java │ ├── SentenceVo.java │ └── SpeakerInfo.java │ └── utils │ ├── HandleAudioUtil.java │ ├── HandleModelConfigUtil.java │ ├── HandleTextUtil.java │ ├── ProgramUtil.java │ └── Result.java └── resources ├── application.properties ├── config.txt ├── static ├── assets │ ├── index-BijUbyZy.css │ └── index-DSxEuOva.js └── favicon.ico └── templates └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qumingzhentmdnan/NovelTTS/62e665ece1c5eda72c4cc1d31a791b0d95541067/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 使用演示视频:https://www.bilibili.com/video/BV1Kx421Q7kS/?spm_id_from=333.999.0.0 2 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.2.0 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | # e.g. to debug Maven itself, use 32 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | # ---------------------------------------------------------------------------- 35 | 36 | if [ -z "$MAVEN_SKIP_RC" ] ; then 37 | 38 | if [ -f /usr/local/etc/mavenrc ] ; then 39 | . /usr/local/etc/mavenrc 40 | fi 41 | 42 | if [ -f /etc/mavenrc ] ; then 43 | . /etc/mavenrc 44 | fi 45 | 46 | if [ -f "$HOME/.mavenrc" ] ; then 47 | . "$HOME/.mavenrc" 48 | fi 49 | 50 | fi 51 | 52 | # OS specific support. $var _must_ be set to either true or false. 53 | cygwin=false; 54 | darwin=false; 55 | mingw=false 56 | case "$(uname)" in 57 | CYGWIN*) cygwin=true ;; 58 | MINGW*) mingw=true;; 59 | Darwin*) darwin=true 60 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 61 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 62 | if [ -z "$JAVA_HOME" ]; then 63 | if [ -x "/usr/libexec/java_home" ]; then 64 | JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME 65 | else 66 | JAVA_HOME="/Library/Java/Home"; export JAVA_HOME 67 | fi 68 | fi 69 | ;; 70 | esac 71 | 72 | if [ -z "$JAVA_HOME" ] ; then 73 | if [ -r /etc/gentoo-release ] ; then 74 | JAVA_HOME=$(java-config --jre-home) 75 | fi 76 | fi 77 | 78 | # For Cygwin, ensure paths are in UNIX format before anything is touched 79 | if $cygwin ; then 80 | [ -n "$JAVA_HOME" ] && 81 | JAVA_HOME=$(cygpath --unix "$JAVA_HOME") 82 | [ -n "$CLASSPATH" ] && 83 | CLASSPATH=$(cygpath --path --unix "$CLASSPATH") 84 | fi 85 | 86 | # For Mingw, ensure paths are in UNIX format before anything is touched 87 | if $mingw ; then 88 | [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && 89 | JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" 90 | fi 91 | 92 | if [ -z "$JAVA_HOME" ]; then 93 | javaExecutable="$(which javac)" 94 | if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then 95 | # readlink(1) is not available as standard on Solaris 10. 96 | readLink=$(which readlink) 97 | if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then 98 | if $darwin ; then 99 | javaHome="$(dirname "\"$javaExecutable\"")" 100 | javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" 101 | else 102 | javaExecutable="$(readlink -f "\"$javaExecutable\"")" 103 | fi 104 | javaHome="$(dirname "\"$javaExecutable\"")" 105 | javaHome=$(expr "$javaHome" : '\(.*\)/bin') 106 | JAVA_HOME="$javaHome" 107 | export JAVA_HOME 108 | fi 109 | fi 110 | fi 111 | 112 | if [ -z "$JAVACMD" ] ; then 113 | if [ -n "$JAVA_HOME" ] ; then 114 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 115 | # IBM's JDK on AIX uses strange locations for the executables 116 | JAVACMD="$JAVA_HOME/jre/sh/java" 117 | else 118 | JAVACMD="$JAVA_HOME/bin/java" 119 | fi 120 | else 121 | JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" 122 | fi 123 | fi 124 | 125 | if [ ! -x "$JAVACMD" ] ; then 126 | echo "Error: JAVA_HOME is not defined correctly." >&2 127 | echo " We cannot execute $JAVACMD" >&2 128 | exit 1 129 | fi 130 | 131 | if [ -z "$JAVA_HOME" ] ; then 132 | echo "Warning: JAVA_HOME environment variable is not set." 133 | fi 134 | 135 | # traverses directory structure from process work directory to filesystem root 136 | # first directory with .mvn subdirectory is considered project base directory 137 | find_maven_basedir() { 138 | if [ -z "$1" ] 139 | then 140 | echo "Path not specified to find_maven_basedir" 141 | return 1 142 | fi 143 | 144 | basedir="$1" 145 | wdir="$1" 146 | while [ "$wdir" != '/' ] ; do 147 | if [ -d "$wdir"/.mvn ] ; then 148 | basedir=$wdir 149 | break 150 | fi 151 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 152 | if [ -d "${wdir}" ]; then 153 | wdir=$(cd "$wdir/.." || exit 1; pwd) 154 | fi 155 | # end of workaround 156 | done 157 | printf '%s' "$(cd "$basedir" || exit 1; pwd)" 158 | } 159 | 160 | # concatenates all lines of a file 161 | concat_lines() { 162 | if [ -f "$1" ]; then 163 | # Remove \r in case we run on Windows within Git Bash 164 | # and check out the repository with auto CRLF management 165 | # enabled. Otherwise, we may read lines that are delimited with 166 | # \r\n and produce $'-Xarg\r' rather than -Xarg due to word 167 | # splitting rules. 168 | tr -s '\r\n' ' ' < "$1" 169 | fi 170 | } 171 | 172 | log() { 173 | if [ "$MVNW_VERBOSE" = true ]; then 174 | printf '%s\n' "$1" 175 | fi 176 | } 177 | 178 | BASE_DIR=$(find_maven_basedir "$(dirname "$0")") 179 | if [ -z "$BASE_DIR" ]; then 180 | exit 1; 181 | fi 182 | 183 | MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR 184 | log "$MAVEN_PROJECTBASEDIR" 185 | 186 | ########################################################################################## 187 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 188 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 189 | ########################################################################################## 190 | wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" 191 | if [ -r "$wrapperJarPath" ]; then 192 | log "Found $wrapperJarPath" 193 | else 194 | log "Couldn't find $wrapperJarPath, downloading it ..." 195 | 196 | if [ -n "$MVNW_REPOURL" ]; then 197 | wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 198 | else 199 | wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 200 | fi 201 | while IFS="=" read -r key value; do 202 | # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) 203 | safeValue=$(echo "$value" | tr -d '\r') 204 | case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; 205 | esac 206 | done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 207 | log "Downloading from: $wrapperUrl" 208 | 209 | if $cygwin; then 210 | wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") 211 | fi 212 | 213 | if command -v wget > /dev/null; then 214 | log "Found wget ... using wget" 215 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" 216 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 217 | wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 218 | else 219 | wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 220 | fi 221 | elif command -v curl > /dev/null; then 222 | log "Found curl ... using curl" 223 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" 224 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 225 | curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 226 | else 227 | curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 228 | fi 229 | else 230 | log "Falling back to using Java to download" 231 | javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" 232 | javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" 233 | # For Cygwin, switch paths to Windows format before running javac 234 | if $cygwin; then 235 | javaSource=$(cygpath --path --windows "$javaSource") 236 | javaClass=$(cygpath --path --windows "$javaClass") 237 | fi 238 | if [ -e "$javaSource" ]; then 239 | if [ ! -e "$javaClass" ]; then 240 | log " - Compiling MavenWrapperDownloader.java ..." 241 | ("$JAVA_HOME/bin/javac" "$javaSource") 242 | fi 243 | if [ -e "$javaClass" ]; then 244 | log " - Running MavenWrapperDownloader.java ..." 245 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" 246 | fi 247 | fi 248 | fi 249 | fi 250 | ########################################################################################## 251 | # End of extension 252 | ########################################################################################## 253 | 254 | # If specified, validate the SHA-256 sum of the Maven wrapper jar file 255 | wrapperSha256Sum="" 256 | while IFS="=" read -r key value; do 257 | case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; 258 | esac 259 | done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 260 | if [ -n "$wrapperSha256Sum" ]; then 261 | wrapperSha256Result=false 262 | if command -v sha256sum > /dev/null; then 263 | if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then 264 | wrapperSha256Result=true 265 | fi 266 | elif command -v shasum > /dev/null; then 267 | if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then 268 | wrapperSha256Result=true 269 | fi 270 | else 271 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." 272 | echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." 273 | exit 1 274 | fi 275 | if [ $wrapperSha256Result = false ]; then 276 | echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 277 | echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 278 | echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 279 | exit 1 280 | fi 281 | fi 282 | 283 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 284 | 285 | # For Cygwin, switch paths to Windows format before running java 286 | if $cygwin; then 287 | [ -n "$JAVA_HOME" ] && 288 | JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") 289 | [ -n "$CLASSPATH" ] && 290 | CLASSPATH=$(cygpath --path --windows "$CLASSPATH") 291 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 292 | MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") 293 | fi 294 | 295 | # Provide a "standardized" way to retrieve the CLI args that will 296 | # work with both Windows and non-Windows executions. 297 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" 298 | export MAVEN_CMD_LINE_ARGS 299 | 300 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 301 | 302 | # shellcheck disable=SC2086 # safe args 303 | exec "$JAVACMD" \ 304 | $MAVEN_OPTS \ 305 | $MAVEN_DEBUG_OPTS \ 306 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 307 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 308 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 309 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Apache Maven Wrapper startup batch script, version 3.2.0 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 28 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 29 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 30 | @REM e.g. to debug Maven itself, use 31 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 32 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 33 | @REM ---------------------------------------------------------------------------- 34 | 35 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 36 | @echo off 37 | @REM set title of command window 38 | title %0 39 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 40 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 41 | 42 | @REM set %HOME% to equivalent of $HOME 43 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 44 | 45 | @REM Execute a user defined script before this one 46 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 47 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 48 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 49 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 50 | :skipRcPre 51 | 52 | @setlocal 53 | 54 | set ERROR_CODE=0 55 | 56 | @REM To isolate internal variables from possible post scripts, we use another setlocal 57 | @setlocal 58 | 59 | @REM ==== START VALIDATION ==== 60 | if not "%JAVA_HOME%" == "" goto OkJHome 61 | 62 | echo. 63 | echo Error: JAVA_HOME not found in your environment. >&2 64 | echo Please set the JAVA_HOME variable in your environment to match the >&2 65 | echo location of your Java installation. >&2 66 | echo. 67 | goto error 68 | 69 | :OkJHome 70 | if exist "%JAVA_HOME%\bin\java.exe" goto init 71 | 72 | echo. 73 | echo Error: JAVA_HOME is set to an invalid directory. >&2 74 | echo JAVA_HOME = "%JAVA_HOME%" >&2 75 | echo Please set the JAVA_HOME variable in your environment to match the >&2 76 | echo location of your Java installation. >&2 77 | echo. 78 | goto error 79 | 80 | @REM ==== END VALIDATION ==== 81 | 82 | :init 83 | 84 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 85 | @REM Fallback to current working directory if not found. 86 | 87 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 88 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 89 | 90 | set EXEC_DIR=%CD% 91 | set WDIR=%EXEC_DIR% 92 | :findBaseDir 93 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 94 | cd .. 95 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 96 | set WDIR=%CD% 97 | goto findBaseDir 98 | 99 | :baseDirFound 100 | set MAVEN_PROJECTBASEDIR=%WDIR% 101 | cd "%EXEC_DIR%" 102 | goto endDetectBaseDir 103 | 104 | :baseDirNotFound 105 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 106 | cd "%EXEC_DIR%" 107 | 108 | :endDetectBaseDir 109 | 110 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 111 | 112 | @setlocal EnableExtensions EnableDelayedExpansion 113 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 114 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 115 | 116 | :endReadAdditionalConfig 117 | 118 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 123 | 124 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 125 | IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | if "%MVNW_VERBOSE%" == "true" ( 132 | echo Found %WRAPPER_JAR% 133 | ) 134 | ) else ( 135 | if not "%MVNW_REPOURL%" == "" ( 136 | SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 137 | ) 138 | if "%MVNW_VERBOSE%" == "true" ( 139 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 140 | echo Downloading from: %WRAPPER_URL% 141 | ) 142 | 143 | powershell -Command "&{"^ 144 | "$webclient = new-object System.Net.WebClient;"^ 145 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 146 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 147 | "}"^ 148 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ 149 | "}" 150 | if "%MVNW_VERBOSE%" == "true" ( 151 | echo Finished downloading %WRAPPER_JAR% 152 | ) 153 | ) 154 | @REM End of extension 155 | 156 | @REM If specified, validate the SHA-256 sum of the Maven wrapper jar file 157 | SET WRAPPER_SHA_256_SUM="" 158 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 159 | IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B 160 | ) 161 | IF NOT %WRAPPER_SHA_256_SUM%=="" ( 162 | powershell -Command "&{"^ 163 | "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ 164 | "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ 165 | " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ 166 | " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ 167 | " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ 168 | " exit 1;"^ 169 | "}"^ 170 | "}" 171 | if ERRORLEVEL 1 goto error 172 | ) 173 | 174 | @REM Provide a "standardized" way to retrieve the CLI args that will 175 | @REM work with both Windows and non-Windows executions. 176 | set MAVEN_CMD_LINE_ARGS=%* 177 | 178 | %MAVEN_JAVA_EXE% ^ 179 | %JVM_CONFIG_MAVEN_PROPS% ^ 180 | %MAVEN_OPTS% ^ 181 | %MAVEN_DEBUG_OPTS% ^ 182 | -classpath %WRAPPER_JAR% ^ 183 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 184 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 185 | if ERRORLEVEL 1 goto error 186 | goto end 187 | 188 | :error 189 | set ERROR_CODE=1 190 | 191 | :end 192 | @endlocal & set ERROR_CODE=%ERROR_CODE% 193 | 194 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 195 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 196 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 197 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 198 | :skipRcPost 199 | 200 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 201 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 202 | 203 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 204 | 205 | cmd /C exit /B %ERROR_CODE% 206 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.2.3 9 | 10 | 11 | com.fjut 12 | NovelTTS 13 | 0.0.1-SNAPSHOT 14 | NovelTTS 15 | NovelTTS 16 | 17 | 21 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-test 29 | test 30 | 31 | 32 | 33 | 34 | com.fasterxml.jackson.core 35 | jackson-databind 36 | 2.15.3 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-thymeleaf 42 | 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-web 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-devtools 53 | true 54 | 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-maven-plugin 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/NovelTtsApplication.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class NovelTtsApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(NovelTtsApplication.class, args); 10 | System.err.println("Server started: http://localhost:8000/handle/index"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/config/MvcConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.config; 2 | 3 | import org.aopalliance.intercept.Interceptor; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 7 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | 10 | @Configuration 11 | public class MvcConfigurer implements WebMvcConfigurer { 12 | @Override 13 | public void addCorsMappings(CorsRegistry registry) { 14 | registry.addMapping("/**") 15 | .allowedOriginPatterns("*") 16 | .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") 17 | .allowedHeaders("*") 18 | .allowCredentials(true); 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/controller/HandleController.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.controller; 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.fjut.noveltts.entity.ArticleData; 6 | import com.fjut.noveltts.entity.SentenceInfo; 7 | import com.fjut.noveltts.entity.SentenceVo; 8 | import com.fjut.noveltts.entity.SpeakerInfo; 9 | import com.fjut.noveltts.utils.*; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import java.io.File; 14 | import java.io.IOException; 15 | import java.nio.file.Files; 16 | import java.nio.file.Paths; 17 | import java.util.*; 18 | import java.util.regex.Matcher; 19 | import java.util.regex.Pattern; 20 | 21 | @Controller 22 | @RequestMapping("/handle") 23 | @CrossOrigin 24 | public class HandleController { 25 | 26 | @GetMapping("/index") 27 | public String toIndex(){ 28 | return "index"; 29 | } 30 | 31 | //将小说角色和朗读声音角色进行绑定添加到配置文件中 32 | @PutMapping("/addBundleConfig") 33 | @ResponseBody 34 | public Result addCharacter(@RequestBody SpeakerInfo[] speakerInfo){ 35 | HashMap map = new HashMap<>(); 36 | for (SpeakerInfo info : speakerInfo) { 37 | if(info.getSpeaker().equals("默认旁白角色")||info.getSpeaker().equals("默认对话角色")) 38 | continue; 39 | map.put(info.getSpeaker(),info.getCharacter()+"@&"+info.getEmotion()); 40 | } 41 | ProgramUtil.addConfig(map); 42 | return Result.ok().message("数据绑定成功"); 43 | } 44 | 45 | @ResponseBody 46 | //得到所有配音角色和朗读声音角色的绑定 47 | @GetMapping("/getBundleConfig") 48 | public Result getBundleConfig(){ 49 | ArrayList speakerInfos = new ArrayList<>(); 50 | Map map = ProgramUtil.getconfig(); 51 | if(map==null) 52 | return null; 53 | for (Map.Entry next : map.entrySet()) { 54 | if(next.getValue().contains("@&")){ 55 | String[] split = next.getValue().split("@&"); 56 | speakerInfos.add(new SpeakerInfo(next.getKey(), split[1], split[0])); 57 | } 58 | } 59 | speakerInfos.add(new SpeakerInfo("默认对话角色",ProgramUtil.getConfigByKey("defaultDialogueEmotion"),ProgramUtil.getConfigByKey("defaultDialogueCharacter"))); 60 | speakerInfos.add(new SpeakerInfo("默认旁白角色",ProgramUtil.getConfigByKey("defaultNarrationEmotion"),ProgramUtil.getConfigByKey("defaultNarrationCharacter"))); 61 | return Result.ok().data("speakerInfos",speakerInfos); 62 | } 63 | 64 | @ResponseBody 65 | //添加配置文件 66 | @PutMapping("/addConfig") 67 | public Result addCharacter(@RequestBody HashMap configMap){ 68 | ProgramUtil.addConfig(configMap); 69 | return Result.ok().message("配置文件添加成功"); 70 | } 71 | 72 | @ResponseBody 73 | //得到所有配音角色 74 | @GetMapping("/getAllCharacter") 75 | public Result getAllCharacter(){ 76 | Map> characterList = ProgramUtil.getCharacterList(); 77 | Set strings = characterList.keySet(); 78 | return Result.ok().data("characterList",strings); 79 | } 80 | 81 | @ResponseBody 82 | //根据配音角色得到所有配音角色所有的感情 83 | @GetMapping("/getEmotionByCharacter") 84 | public Result getEmotionByCharacter(String character){ 85 | Map> characterList = ProgramUtil.getCharacterList(); 86 | List strings = characterList.get(character); 87 | return Result.ok().data("emotionList",strings); 88 | } 89 | 90 | @ResponseBody 91 | //查询配置文件中的所有配音角色及所有情感 92 | @GetMapping("/getAllCharacterAndEmotion") 93 | public Result getCharacterInfo(){ 94 | Map> characterList = ProgramUtil.getCharacterList(); 95 | return Result.ok().data("characterInConfig",characterList); 96 | } 97 | 98 | @ResponseBody 99 | @DeleteMapping("/deleteConfig") 100 | public Result deleteConfig(String speaker){ 101 | ProgramUtil.deleteConfig(speaker); 102 | return Result.ok().message("删除成功"); 103 | } 104 | 105 | @ResponseBody 106 | //转换模型配置文件 107 | @GetMapping("/handleModelConfig") 108 | public Result handleModelConfig(String modelPath){ 109 | if(!Files.isDirectory(Paths.get(modelPath))) 110 | return Result.error().message("未配置文件夹路径或错误的文件夹路径"); 111 | HandleModelConfigUtil.setConfigFile(modelPath); 112 | return Result.ok().message("模型配置文件转换成功"); 113 | } 114 | 115 | 116 | @ResponseBody 117 | //进行小说文件切分,以章切分为一个文件 118 | @GetMapping("/splitArticle") 119 | public Result splitArticle(String novelPath){ 120 | //写入配置文件 121 | ProgramUtil.addConfig("novelPath",novelPath.replace(".txt","")); 122 | if(!novelPath.endsWith(".txt")) 123 | return Result.error().message("错误的文件格式,小说需为txt类型"); 124 | if(!Files.isRegularFile(Paths.get(novelPath))) 125 | return Result.error().message("小说未配置文件路径或错误的文件路径"); 126 | HandleTextUtil.splitArticle(novelPath); 127 | return Result.ok().message("小说切分成功,请前往"+novelPath.replace(".txt","")+"查看"); 128 | } 129 | 130 | @ResponseBody 131 | //得到所有切分后的文件名 132 | @GetMapping("/getArticleList") 133 | public Result getArticleList(){ 134 | String novelPath = ProgramUtil.getConfigByKey("novelPath"); 135 | if(novelPath==null) 136 | return Result.error().message("未配置小说文件路径"); 137 | String[] list = new File(novelPath).list(); 138 | if(list==null) 139 | return Result.error().message("未找到切分后的小说文件"); 140 | Arrays.sort(list, (s1, s2) -> { 141 | Pattern p = Pattern.compile("^\\d+"); 142 | Matcher m1 = p.matcher(s1); 143 | Matcher m2 = p.matcher(s2); 144 | if (m1.find() && m2.find()) { 145 | return Integer.compare(Integer.parseInt(m1.group()), Integer.parseInt(m2.group())); 146 | } 147 | return s1.compareTo(s2); 148 | }); 149 | return Result.ok().data("getArticleList",list); 150 | } 151 | 152 | @ResponseBody 153 | //返回一章小说切分和说话人,并且预测结果 154 | @GetMapping("/getHandledArticle") 155 | public Result getHandledArticle(String articleName){ 156 | String novelPath = ProgramUtil.getConfigByKey("novelPath"); 157 | if(novelPath==null) 158 | return Result.error().message("未配置小说文件路径"); 159 | ArrayList sentenceInfos = HandleTextUtil.formatArticle(novelPath.replace(".txt", "") + "/" + articleName); 160 | if(sentenceInfos==null) 161 | return Result.error(); 162 | return Result.ok().data("sentenceInfos",sentenceInfos); 163 | } 164 | 165 | @ResponseBody 166 | //接受调整成功的小说内容,对其进行转语音 167 | //测试 168 | @PostMapping("/saveFormatArticle") 169 | public Result saveFormatArticle(@RequestBody ArticleData articleData){ 170 | if(articleData.getNovelName()==null) 171 | return Result.error().message("小说名不能为空"); 172 | String novelPath = ProgramUtil.getConfigByKey("novelPath")+"format/"; 173 | new File(novelPath).mkdirs(); 174 | HandleTextUtil.saveFormatArticle(novelPath+articleData.getNovelName(),articleData.getSentenceInfo()); 175 | return Result.ok(); 176 | } 177 | 178 | @ResponseBody 179 | @GetMapping("/novelTTS") 180 | public Result novelTTS(){ 181 | try { 182 | String novelPath = ProgramUtil.getConfigByKey("novelPath"); 183 | ArrayList sentenceInfo = null; 184 | File[] files = new File(novelPath+"format/").listFiles(); 185 | for (File file : files) { 186 | // 创建 ObjectMapper 对象 187 | ObjectMapper mapper = new ObjectMapper(); 188 | // 读取 JSON 文件并转换为 ArrayList 对象 189 | sentenceInfo = mapper.readValue(file, new TypeReference>(){}); 190 | HandleAudioUtil.textToAudio(sentenceInfo,novelPath); 191 | boolean delete = file.delete(); 192 | if(delete) 193 | System.out.println(file+"已合成,删除文件成功"); 194 | } 195 | } catch (IOException e) { 196 | throw new RuntimeException(e); 197 | } 198 | return Result.ok(); 199 | } 200 | } -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/entity/ArticleData.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.entity; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class ArticleData { 6 | private ArrayList sentenceInfo; 7 | private String novelName; 8 | 9 | public ArrayList getSentenceInfo() { 10 | return sentenceInfo; 11 | } 12 | 13 | public void setSentenceInfo(ArrayList sentenceInfo) { 14 | this.sentenceInfo = sentenceInfo; 15 | } 16 | 17 | public String getNovelName() { 18 | return novelName; 19 | } 20 | 21 | public void setNovelName(String novelName) { 22 | this.novelName = novelName; 23 | } 24 | 25 | // getters and setters 26 | } -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/entity/SentenceInfo.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.entity; 2 | 3 | public class SentenceInfo { 4 | //是否是对话 5 | private boolean dialogue; 6 | //批处理大小 7 | private Integer batchSize=1; 8 | //句子 9 | private String sentence; 10 | //说话者 11 | private String speaker; 12 | //配音角色 13 | private String character; 14 | //情感 15 | private String emotion="default"; 16 | 17 | private double speed=1.0; 18 | 19 | public String getEmotion() { 20 | return emotion; 21 | } 22 | 23 | public void setEmotion(String emotion) { 24 | this.emotion = emotion; 25 | } 26 | 27 | public SentenceInfo(boolean isDialogue, String sentence) { 28 | this.dialogue = isDialogue; 29 | this.sentence = sentence; 30 | } 31 | 32 | public boolean isDialogue() { 33 | return dialogue; 34 | } 35 | 36 | public void setDialogue(boolean dialogue) { 37 | this.dialogue = dialogue; 38 | } 39 | 40 | public Integer getBatchSize() { 41 | return batchSize; 42 | } 43 | 44 | public void setBatchSize(Integer batchSize) { 45 | this.batchSize = batchSize; 46 | } 47 | 48 | public double getSpeed() { 49 | return speed; 50 | } 51 | 52 | public void setSpeed(double speed) { 53 | this.speed = speed; 54 | } 55 | 56 | public String getSentence() { 57 | return sentence; 58 | } 59 | 60 | public void setSentence(String sentence) { 61 | this.sentence = sentence; 62 | } 63 | 64 | public String getSpeaker() { 65 | return speaker; 66 | } 67 | 68 | public void setSpeaker(String speaker) { 69 | this.speaker = speaker; 70 | } 71 | 72 | public SentenceInfo() { 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "SentenceInfo{" + 78 | "isDialogue=" + dialogue + 79 | ", batchSize=" + batchSize + 80 | ", sentence='" + sentence + '\'' + 81 | ", speaker='" + speaker + '\'' + 82 | ", character='" + character + '\'' + 83 | ", emotion='" + emotion + '\'' + 84 | ", speed=" + speed + 85 | '}'; 86 | } 87 | 88 | public String getCharacter() { 89 | return character; 90 | } 91 | 92 | public void setCharacter(String character) { 93 | this.character = character; 94 | } 95 | } -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/entity/SentenceVo.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.entity; 2 | 3 | public class SentenceVo { 4 | //句子 5 | private String sentence; 6 | //说话者 7 | private String speaker; 8 | 9 | public SentenceVo(String sentence, String speaker) { 10 | this.sentence = sentence; 11 | this.speaker = speaker; 12 | } 13 | 14 | public SentenceVo() { 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/entity/SpeakerInfo.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.entity; 2 | 3 | public class SpeakerInfo { 4 | String speaker; 5 | String emotion; 6 | String character; 7 | 8 | @Override 9 | public String toString() { 10 | return "SpeakerInfo{" + 11 | "speaker='" + speaker + '\'' + 12 | ", emotion='" + emotion + '\'' + 13 | ", character='" + character + '\'' + 14 | '}'; 15 | } 16 | 17 | public String getSpeaker() { 18 | return speaker; 19 | } 20 | 21 | public void setSpeaker(String speaker) { 22 | this.speaker = speaker; 23 | } 24 | 25 | public String getEmotion() { 26 | return emotion; 27 | } 28 | 29 | public void setEmotion(String emotion) { 30 | this.emotion = emotion; 31 | } 32 | 33 | public String getCharacter() { 34 | return character; 35 | } 36 | 37 | public void setCharacter(String character) { 38 | this.character = character; 39 | } 40 | 41 | public SpeakerInfo() { 42 | } 43 | 44 | public SpeakerInfo(String speaker, String emotion, String character) { 45 | this.speaker = speaker; 46 | this.emotion = emotion; 47 | this.character = character; 48 | } 49 | } -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/utils/HandleAudioUtil.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.utils; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fjut.noveltts.entity.SentenceInfo; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.sound.sampled.AudioFileFormat; 9 | import javax.sound.sampled.AudioInputStream; 10 | import javax.sound.sampled.AudioSystem; 11 | import java.io.*; 12 | import java.net.HttpURLConnection; 13 | import java.net.URL; 14 | import java.nio.charset.StandardCharsets; 15 | import java.nio.file.Files; 16 | import java.util.*; 17 | 18 | import static com.fjut.noveltts.utils.HandleTextUtil.formatArticle; 19 | 20 | @Component 21 | public class HandleAudioUtil { 22 | //将一段文本转换为音频 23 | private static boolean getAudio(String filePath,String character,String emotion,String text,Integer batch_size,Double speed) throws IOException { 24 | 25 | String url = ProgramUtil.getConfigByKey("url"); 26 | if(url==null||url.isEmpty()) 27 | System.err.println("HandleAudioUtil=>getAudio:未配置url"); 28 | URL obj = new URL(url+"tts"); 29 | //URL obj = new URL("http://localhost:5000/tts"); 30 | HttpURLConnection con = (HttpURLConnection) obj.openConnection(); 31 | 32 | // 设置请求方法 33 | con.setRequestMethod("POST"); 34 | // 发送Post请求 35 | con.setDoOutput(true); 36 | // 创建一个Map来存储参数 37 | Map params = new HashMap<>(); 38 | if(character!=null&&!character.isEmpty()) 39 | params.put("character", character);//早期版本GPT-Sovits-Interface中参数名为cha_name 40 | if(emotion!=null&&!emotion.isEmpty()) 41 | params.put("emotion", emotion);//早期版本GPT-Sovits-Interface中参数名为cha_name 42 | if(batch_size!=null) 43 | params.put("batch_size", batch_size); 44 | if(text!=null&&!text.isEmpty()) 45 | params.put("text", text); 46 | if(speed!=null) 47 | params.put("speed", speed); 48 | params.put("text_language","中文"); 49 | // 将Map转换为JSON格式的字符串 50 | ObjectMapper objectMapper = new ObjectMapper(); 51 | String jsonParams = objectMapper.writeValueAsString(params); 52 | System.out.println(jsonParams); 53 | // 设置请求头,表示我们发送的是JSON格式的数据 54 | con.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); 55 | 56 | OutputStream os = con.getOutputStream(); 57 | os.write(jsonParams.getBytes(StandardCharsets.UTF_8)); 58 | os.flush(); 59 | os.close(); 60 | // 发送请求并获取响应码 61 | int responseCode = con.getResponseCode(); 62 | 63 | // 获取输入流 64 | InputStream inputStream = con.getInputStream(); 65 | 66 | // 创建一个输出流,用于写入文件 67 | OutputStream outputStream = new FileOutputStream(filePath); 68 | // 创建一个缓冲区 69 | byte[] buffer = new byte[1024]; 70 | int bytesRead; 71 | // 在循环中读取数据,直到没有更多数据可读 72 | while ((bytesRead = inputStream.read(buffer)) != -1) { 73 | outputStream.write(buffer, 0, bytesRead); 74 | } 75 | // 关闭输入流和输出流 76 | inputStream.close(); 77 | outputStream.close(); 78 | return responseCode== 200; 79 | } 80 | 81 | public static boolean textToAudio(ArrayList text, String path) { 82 | try { 83 | int index = 0; 84 | String title=text.get(0).getSentence().replace("。",""); 85 | String dir = path + "audio/" +title+ "/"; 86 | File file = new File(dir); 87 | if(!file.exists()) 88 | file.mkdirs(); 89 | 90 | for (SentenceInfo sentenceInfo : text) { 91 | String sentence = sentenceInfo.getSentence(); 92 | String[] split = sentence.split("(?<=[。!?;……])"); 93 | for (String s : split) { 94 | if(!s.matches(".*[\u4e00-\u9fa5]+.*")) 95 | continue; 96 | System.out.println(s); 97 | boolean audio = getAudio(dir+(index++) + ".wav", sentenceInfo.getCharacter(), sentenceInfo.getEmotion(), s, sentenceInfo.getBatchSize(), sentenceInfo.getSpeed()); 98 | } 99 | // System.out.println(sentenceInfo.getSentence()); 100 | // boolean audio = getAudio(dir+(index++) + ".wav", sentenceInfo.getCharacter(), sentenceInfo.getEmotion(), sentenceInfo.getSentence(), sentenceInfo.getBatchSize(), sentenceInfo.getSpeed()); 101 | } 102 | mergeAndDeleteAudioFiles(path + "audio/", title); 103 | file.delete(); 104 | } catch (Exception e) { 105 | System.err.println("textToAudio=>"+e); 106 | } 107 | return true; 108 | } 109 | 110 | private static void mergeAndDeleteAudioFiles(String directoryPath, String title) throws Exception { 111 | // 创建一个File对象,表示指定路径的目录 112 | File dir = new File(directoryPath+title); 113 | // 获取目录下所有以.wav结尾的文件 114 | File[] files = dir.listFiles((d, name) -> name.endsWith(".wav")); 115 | // 如果没有找到任何.wav文件,抛出异常 116 | if (files == null || files.length == 0) { 117 | throw new Exception("No wav files found in the directory."); 118 | } 119 | Arrays.sort(files, Comparator.comparingInt(file -> Integer.parseInt(file.getName().replace(".wav", "")))); 120 | 121 | // 获取第一个.wav文件的音频输入流和音频文件格式 122 | AudioInputStream audioInputStream; 123 | AudioFileFormat format = AudioSystem.getAudioFileFormat(files[0]); 124 | 125 | // 创建一个字节数组输出流,用于存储所有.wav文件的数据 126 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 127 | // 创建一个缓冲区 128 | byte[] buffer = new byte[1024]; 129 | int read; 130 | 131 | // 遍历所有.wav文件 132 | for (File file : files) { 133 | // 获取当前.wav文件的音频输入流 134 | audioInputStream = AudioSystem.getAudioInputStream(file); 135 | // 读取音频输入流的数据,并写入到字节数组输出流中 136 | while ((read = audioInputStream.read(buffer)) > 0) { 137 | outputStream.write(buffer, 0, read); 138 | } 139 | // 关闭音频输入流 140 | audioInputStream.close(); 141 | } 142 | 143 | // 将字节数组输出流转换为字节数组 144 | byte[] outputBytes = outputStream.toByteArray(); 145 | // 创建一个字节数组输入流 146 | InputStream byteArrayInputStream = new ByteArrayInputStream(outputBytes); 147 | // 将字节数组输入流转换为音频输入流 148 | AudioInputStream outputAudioInputStream = new AudioInputStream(byteArrayInputStream, format.getFormat(), outputBytes.length / format.getFormat().getFrameSize()); 149 | // 将音频输入流写入到一个新的.wav文件中 150 | AudioSystem.write(outputAudioInputStream, format.getType(), new File(directoryPath + title + ".wav")); 151 | 152 | // 删除原先的.wav文件 153 | for (File file : files) { 154 | Files.delete(file.toPath()); 155 | } 156 | } 157 | 158 | // public static void main(String[] args) throws IOException { 159 | // BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\audio\\text.txt")); 160 | // String str; 161 | // int index=0; 162 | // while((str=bufferedReader.readLine())!=null){ 163 | // System.out.println(str); 164 | // getAudio("E:\\audio\\res2\\"+(index++)+(str.length()>100?str.substring(0,100):str)+".wav","卡芙卡","悲伤",str,50,1.0); 165 | // } 166 | // } 167 | } -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/utils/HandleModelConfigUtil.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.utils; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | import java.io.File; 6 | import java.io.FileWriter; 7 | import java.io.FilenameFilter; 8 | import java.io.IOException; 9 | import java.util.HashMap; 10 | 11 | //生成模型配置文件 12 | public class HandleModelConfigUtil { 13 | //要转化的模型来自https://space.bilibili.com/518098961/?spm_id_from=333.999.0.0,格式如下 14 | // 参考音频(文件夹) 15 | // xxx.pth(文件) 16 | // xxx.ckpt(文件) 17 | // 训练日志.log(文件) 18 | 19 | //以下方法用于用于创建模型配置文件,GPT-Sovits-Interface项目中的模型配置文件格式如下 20 | // { 21 | // "emotion_list": { 22 | // "default": { 23 | // "prompt_language": "中文", 24 | // "prompt_text": "激动说话-既然密钥找到了就赶快开始吧,电梯的权限用那边的操作台就能解锁。", 25 | // "ref_wav_path": "参考音频\\激动说话-既然密钥找到了就赶快开始吧,电梯的权限用那边的操作台就能解锁。.wav" 26 | // } 27 | // }, 28 | // "简介": "这是一个配置文件适用于https://github.com/X-T-E-R/TTS-for-GPT-soVITS,是一个简单好用的前后端项目", 29 | // "sovits_path": "阿兰_e25_s525.pth", 30 | // "version": "1.0.1", 31 | // "gpt_path": "阿兰-e10.ckpt" 32 | // } 33 | 34 | //创建配置文件 35 | public static void setConfigFile(String filePath){ 36 | try { 37 | //打开模型存放文件夹,如"E:\GPT-Sovits\GPT-SoVITS-Inference\trained" 38 | File modelFolders = new File(filePath); 39 | File[] modelsFolders = modelFolders.listFiles(File::isDirectory); 40 | for (File modelFolder : modelsFolders) { 41 | //遍历文件夹,路径如"E:\GPT-Sovits\GPT-SoVITS-Inference\trained\阿兰 42 | File modelPath = modelFolder.getCanonicalFile(); 43 | 44 | //设置基础配置 45 | HashMap configMap = new HashMap<>(); 46 | setBaseConfig(modelFolder,configMap); 47 | //设置情感配置 48 | HashMap emoConfig = setEmoConfig(modelFolder); 49 | if(emoConfig==null) 50 | continue; 51 | configMap.put("emotion_list",emoConfig); 52 | // 将对象转化为 JSON 格式的字符串 53 | String json = new ObjectMapper().writeValueAsString(configMap); 54 | 55 | //将文件写入到指定文件夹下的infer_config.json 56 | File out = new File(modelPath + "/" + "infer_config.json"); 57 | //如果文件不存在则创建文件 58 | if (!out.exists()) 59 | out.createNewFile(); 60 | 61 | //写入文件,刷新缓冲区,关闭文件 62 | FileWriter fileWriter = new FileWriter(out); 63 | fileWriter.write(json); 64 | fileWriter.flush(); 65 | fileWriter.close(); 66 | } 67 | } catch (IOException e) { 68 | System.err.println("setConfigFile=>"+e); 69 | } 70 | } 71 | 72 | //创建基础配置文件 73 | private static void setBaseConfig(File file, HashMap configMap){ 74 | //file路径如"E:\GPT-Sovits\GPT-SoVITS-Inference\trained\阿兰 75 | configMap.put("version","1.0.1"); 76 | configMap.put("简介","这是一个配置文件适用于https://github.com/X-T-E-R/TTS-for-GPT-soVITS,是一个简单好用的前后端项目"); 77 | String[] list = file.list((dir, name) -> name.endsWith(".ckpt") || name.endsWith(".pth")); 78 | //遍历文件夹下的文件,将.pth文件赋值给sovits_path,将.ckpt文件赋值给gpt_path 79 | for (String path : list) { 80 | if(path.endsWith(".ckpt")) 81 | configMap.put("gpt_path",path); 82 | else 83 | configMap.put("sovits_path",path); 84 | } 85 | } 86 | 87 | //用于创建情感配置文件 88 | private static HashMap setEmoConfig(File file){ 89 | //file路径如E:\GPT-Sovits\GPT-SoVITS-Inference\trained\阿兰 90 | HashMap res = new HashMap<>(); 91 | File[] files = file.listFiles(File::isDirectory); 92 | if(files==null||files.length<=0) 93 | return null; 94 | File[] audioDirList = files[0].listFiles(); 95 | //开始遍历参考音频,audioDir路径为E:\GPT-Sovits\GPT-SoVITS-Inference\trained\阿兰\参考音频 96 | for (File audioDir : audioDirList) { 97 | HashMap map = new HashMap<>(); 98 | map.put("prompt_language","中文"); 99 | String dirName=audioDir.getName(); 100 | //如果是文件,则直接赋值给default,路径为E:\GPT-Sovits\GPT-SoVITS-Inference\trained\阿兰\参考音频\xxx.wav 101 | if(audioDir.isFile()){ 102 | String[] split = dirName.split("-"); 103 | map.put("ref_wav_path","参考音频/"+dirName); 104 | if(dirName.contains("-")){ 105 | map.put("prompt_text",split[1].replace(".wav","")); 106 | res.put(split[0],map); 107 | }else{ 108 | map.put("prompt_text",dirName.replace(".wav","")); 109 | res.put("default",map); 110 | } 111 | }else{ 112 | //如果是文件夹,则遍历文件夹下的文件,找出最大的文件 113 | File[] audioFileList = audioDir.listFiles(); 114 | File maxFile = null; 115 | long maxSize = 0; 116 | for (File audioFile : audioFileList) { 117 | if (audioFile.length() > maxSize&&!audioFile.getName().replace(".wav","").matches(".*[a-zA-Z].*")) { 118 | maxSize = audioFile.length(); 119 | maxFile = audioFile; 120 | } 121 | } 122 | if(maxFile!=null){ 123 | //ref_wav_path路径形如E:\GPT-Sovits\GPT-SoVITS-Inference\trained\阿兰\参考音频\开心(或其他情绪)\xxx.wav 124 | map.put("ref_wav_path","参考音频/"+dirName+"/"+maxFile.getName()); 125 | map.put("prompt_text",maxFile.getName().replace(".wav","").replaceAll("【.*?】", "")); 126 | res.put(dirName,map); 127 | } 128 | } 129 | } 130 | return res; 131 | } 132 | } -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/utils/HandleTextUtil.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.utils; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fjut.noveltts.entity.SentenceInfo; 5 | 6 | import java.io.*; 7 | import java.util.*; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | public class HandleTextUtil { 12 | 13 | 14 | 15 | //将一本小说按照“第xxx章 标题”,分割成多个文件,每个文件对应一章 16 | public static void splitArticle(String path){ 17 | try { 18 | int i=1; 19 | //创建文件夹 20 | File resFile = new File(path.replace(".txt", "")); 21 | if (!resFile.exists()) { 22 | resFile.mkdirs(); 23 | } 24 | 25 | //创建文件读取流 26 | BufferedReader bufferedReader = new BufferedReader(new FileReader(path)); 27 | //用于储存读取到的行内容 28 | String line = null; 29 | //在读取到章节名称之后,储存章节名,用于在while中(nextLine != null)利用||截断特性,跳过此处line的读取 30 | String nextLine = null; 31 | 32 | //定义一个正则表达式,匹配“第xxx章 标题” 33 | Pattern chapterPattern = Pattern.compile("^.*第.{0,15}章.*$"); 34 | 35 | //读取文件内容 36 | while ((nextLine != null) || (line = bufferedReader.readLine()) != null) { 37 | //如果匹配到章节名称 38 | if (chapterPattern.matcher(line).matches()) { 39 | //以章节名创建文件,i用于文件排序 40 | String chapterName = (i++)+line; 41 | File chapterFile = new File(resFile, chapterName + ".txt"); 42 | //创建文件写入流 43 | BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(chapterFile)); 44 | // 将章节名称写入到文件中,并换行,使用“。”包裹,避免对话切割时与正文相连 45 | bufferedWriter.write('“' + chapterName.replace("“","").replace("”","") + "。”"); 46 | bufferedWriter.newLine(); 47 | 48 | //从标题后开始读取,直到下一个章节名称之前 49 | while ((nextLine = bufferedReader.readLine()) != null) { 50 | //如果匹配到章节名称,赋值给nextLine和line,跳出循环 51 | if (chapterPattern.matcher(nextLine).matches()) { 52 | line = nextLine; 53 | break; 54 | } 55 | bufferedWriter.write(nextLine.replace("?","?").replace("!","!") 56 | .replace(".","。").replace(";",";").replace("「","“").replace("」","”").replace("……?","啊")); 57 | bufferedWriter.newLine(); 58 | } 59 | bufferedWriter.close(); 60 | } 61 | } 62 | bufferedReader.close(); 63 | } catch (IOException e) { 64 | System.err.println("splitArticle=>"+e); 65 | } 66 | } 67 | 68 | 69 | //读取一章的内容,并将其分隔为对话和非对话两部分 70 | //对话部分以“ 。”或 “ !”或 “ ……”或 “ ?”包裹,非对话部分以对话部分之间的内容。如果文章未按照规范格式书写,可能会出现错误 71 | public static ArrayList formatArticle(String path) { 72 | try { 73 | //创建集合储存对话和非对话 74 | ArrayList SentenceInfos = new ArrayList<>(); 75 | //根据文件名创建文件读取流 76 | FileReader fileReader = new FileReader(path); 77 | char[] str = new char[100000]; 78 | //用于替换换行符 79 | String wrap = "\r\n"; 80 | int legth = 0; 81 | //读取文件内容 82 | while ((legth=fileReader.read(str)) != -1) { 83 | StringBuilder string = new StringBuilder(new String(str)); 84 | // 定义一个正则表达式,匹配任何以句号、感叹号或问号结束的字符串 85 | Pattern pattern = Pattern.compile("“[^“”]*?(“[^“”]*?”[^“”]*?)*?[,;。!?……—]”"); 86 | // 获取一个 Matcher,用于匹配当前行 87 | Matcher matcher = pattern.matcher(string); 88 | int begin = 0; 89 | // 查找匹配的字符串 90 | while (matcher.find()) { 91 | //如果匹配的字符串不是从头开始的,将匹配字符串之前的字符串加入到集合中,对话之前的就是非对话 92 | if (matcher.start() != begin) { 93 | //截取非对话部分,替换无效字符 94 | String replace = string.substring(begin, matcher.start()).replace(wrap, "").replace(" ", "").replace(" ","");//replace((char)12288,' ').replace(" ",""); 95 | //如果不为空,将非对话部分加入到集合中 96 | if (!replace.isEmpty()) 97 | SentenceInfos.add(new SentenceInfo(false, replace)); 98 | } 99 | //截取对话部分,替换无效字符 100 | String replace = matcher.group().replace(wrap, "").replace(" ", "").replace(" ","");//replace((char)12288,' ').replace(" ",""); 101 | SentenceInfos.add(new SentenceInfo(true, replace)); 102 | begin = matcher.end(); 103 | } 104 | if(begin!=legth) 105 | SentenceInfos.add(new SentenceInfo(false, string.substring(begin,legth))); 106 | } 107 | //关闭文件读取流 108 | fileReader.close(); 109 | 110 | setSpeaker(SentenceInfos); 111 | //返回结果集 112 | return SentenceInfos; 113 | } catch (IOException e) { 114 | System.err.println("formatArticle=>"+e); 115 | return null; 116 | } 117 | } 118 | 119 | public static void saveFormatArticle(String path,ArrayList sentenceInfo) { 120 | try { 121 | // 创建 ObjectMapper 对象 122 | ObjectMapper mapper = new ObjectMapper(); 123 | // 将 ArrayList 对象转换为 JSON 字符串 124 | String json = mapper.writeValueAsString(sentenceInfo); 125 | // 创建 FileWriter 对象 126 | FileWriter writer = new FileWriter(path); 127 | // 将 JSON 字符串写入到文件中 128 | writer.write(json); 129 | // 关闭 FileWriter 130 | writer.close(); 131 | } catch (IOException e) { 132 | System.err.println("saveFormatArticle=>"+e); 133 | } 134 | } 135 | 136 | //从前后旁白中找出说话者 137 | private static void setSpeaker(ArrayList list) { 138 | int index = 0, size = list.size(); 139 | SentenceInfo tmp = null; 140 | //读取默认配置 141 | double speed= ProgramUtil.getConfigByKey("speed") == null ? 1.0 : Double.parseDouble(ProgramUtil.getConfigByKey("speed")); 142 | int batchSize= ProgramUtil.getConfigByKey("batchSize") == null ? 1 : Integer.parseInt(ProgramUtil.getConfigByKey("batchSize")); 143 | 144 | String defaultNarrationCharacter = ProgramUtil.getConfigByKey("defaultNarrationCharacter"); 145 | String defaultNarrationEmotion = ProgramUtil.getConfigByKey("defaultNarrationEmotion"); 146 | //遍历集合中的所有句子 147 | for (SentenceInfo sentenceInfo : list) { 148 | sentenceInfo.setSpeed(speed); 149 | sentenceInfo.setBatchSize(batchSize); 150 | sentenceInfo.setSpeaker("默认旁白角色"); 151 | sentenceInfo.setCharacter(defaultNarrationCharacter); 152 | sentenceInfo.setEmotion(defaultNarrationEmotion); 153 | //如果当前句子是对话,从前后旁白中找出说话者(近似查找 154 | if (sentenceInfo.isDialogue()) { 155 | //如果前一个存在,且不是对话,从前一个句子中找出说话者,否则从后一个句子中找出说话者,如果都不存在,不做处理 156 | if (index - 1 >= 0 && (!((tmp = list.get(index - 1)).isDialogue()))) { 157 | getMinSpeaker(tmp.getSentence(), sentenceInfo); 158 | } else if (index + 1 < size && (!((tmp = list.get(index + 1)).isDialogue()))) { 159 | getMinSpeaker(tmp.getSentence(), sentenceInfo); 160 | } 161 | } 162 | index++; 163 | } 164 | } 165 | 166 | //找到传入句子(对话的前一句或者后一句)中存在与set集合中,第一个出现的说话者 167 | private static void getMinSpeaker(String lastOrNextSentence, SentenceInfo nowSentence) { 168 | //获取所有配置文件 169 | Map characterMap = ProgramUtil.getCharacterConfig(); 170 | Set speakerSet =characterMap.keySet(); 171 | 172 | //如果是章节名,不做处理 173 | Pattern chapterPattern = Pattern.compile("^.*第.{0,15}章.*$"); 174 | String sentence = nowSentence.getSentence(); 175 | if (chapterPattern.matcher(sentence).matches()) { 176 | String res = sentence.replace("“", "").replace("”", "") 177 | .replace("。", "").replace("章", "章。") 178 | .replaceAll("\\d", ""); 179 | nowSentence.setSentence(res); 180 | nowSentence.setDialogue(false); 181 | return; 182 | } 183 | 184 | int minIndex = Integer.MAX_VALUE; 185 | String minSpeaker = null; 186 | //找到传入句子(对话的前一句或者后一句)中存在与set集合中,第一个出现的说话者 187 | for (String s : speakerSet) { 188 | int i = lastOrNextSentence.indexOf(s); 189 | if (i != -1 && i < minIndex) { 190 | minIndex = i; 191 | minSpeaker = s; 192 | } 193 | } 194 | //如果找到了说话者,将说话者赋值给当前句子,否则不做处理 195 | if (minSpeaker != null) { 196 | String[] split= characterMap.get(minSpeaker).split("@&"); 197 | nowSentence.setCharacter(split[0]); 198 | nowSentence.setEmotion(split[1]); 199 | nowSentence.setSpeaker(minSpeaker); 200 | }else{ 201 | nowSentence.setSpeaker("默认对话角色"); 202 | nowSentence.setCharacter(ProgramUtil.getConfigByKey("defaultDialogueCharacter")); 203 | nowSentence.setEmotion(ProgramUtil.getConfigByKey("defaultDialogueEmotion")); 204 | } 205 | } 206 | 207 | 208 | } -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/utils/ProgramUtil.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.utils; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | import java.io.*; 6 | import java.net.URI; 7 | import java.net.http.HttpClient; 8 | import java.net.http.HttpRequest; 9 | import java.net.http.HttpResponse; 10 | import java.util.*; 11 | 12 | //用于读写txt文件中写入配置 13 | public class ProgramUtil { 14 | private static String path="./config.txt"; 15 | //向配置文件中添加配置 16 | public static void addConfig(Map map) { 17 | try { 18 | Properties properties = new Properties(); 19 | properties.load(new FileReader(path)); 20 | properties.putAll(map); 21 | properties.store(new FileWriter(path), null); 22 | } catch (IOException e) { 23 | System.err.println("addConfig=>"+e); 24 | } 25 | } 26 | //向配置文件中添加配置 27 | public static void addConfig(String key,String value) { 28 | try { 29 | Properties properties = new Properties(); 30 | properties.load(new FileReader(path)); 31 | properties.setProperty(key,value); 32 | properties.store(new FileWriter(path), null); 33 | } catch (IOException e) { 34 | System.err.println("addConfig=>"+e); 35 | } 36 | } 37 | 38 | //返回配置文件中的所有配置 39 | public static Map getconfig() { 40 | try { 41 | Properties properties = new Properties(); 42 | properties.load(new FileReader(path)); 43 | Map stringMap = new HashMap<>(); 44 | for (Map.Entry entry : properties.entrySet()) { 45 | stringMap.put(entry.getKey().toString(), entry.getValue().toString()); 46 | } 47 | return stringMap; 48 | } catch (IOException e) { 49 | System.err.println("getconfig=>"+e); 50 | } 51 | return null; 52 | } 53 | 54 | //返回配置文件中所有的角色语音、情感配置 55 | public static Map getCharacterConfig() { 56 | Map map = getconfig(); 57 | if(map!=null) 58 | map.entrySet().removeIf(entry -> !entry.getValue().contains("@&")); 59 | return map; 60 | } 61 | 62 | //从配置文件中,通过key得到value 63 | public static String getConfigByKey(String key) { 64 | Map config = getconfig(); 65 | if(config==null||config.get(key)==null) 66 | return null; 67 | return config.get(key); 68 | } 69 | 70 | //得到角色及角色情感列表 71 | public static Map> getCharacterList() { 72 | try { 73 | String url = ProgramUtil.getConfigByKey("url"); 74 | if(url==null||url.isEmpty()) 75 | throw new IOException("未配置url"); 76 | HttpClient client = HttpClient.newHttpClient(); 77 | HttpRequest request = HttpRequest.newBuilder() 78 | .uri(new URI(url+"character_list")) 79 | .build(); 80 | HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); 81 | String json = response.body(); 82 | ObjectMapper mapper = new ObjectMapper(); 83 | Map> map = mapper.readValue(json, Map.class); 84 | return map; 85 | } catch (Exception e) { 86 | System.err.println("getCharacterList=>"+e); 87 | } 88 | return null; 89 | } 90 | 91 | public static void deleteConfig(String speaker) { 92 | try { 93 | Properties properties = new Properties(); 94 | properties.load(new FileReader(path)); 95 | properties.remove(speaker); 96 | properties.store(new FileWriter(path), null); 97 | } catch (IOException e) { 98 | System.err.println("getconfig=>"+e); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/fjut/noveltts/utils/Result.java: -------------------------------------------------------------------------------- 1 | package com.fjut.noveltts.utils; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | 7 | 8 | public class Result { 9 | private Boolean success; 10 | 11 | private Integer code; 12 | 13 | private String message; 14 | 15 | public static final Integer SUCCESS = 20000; 16 | 17 | public static final Integer ERROR = 20001; 18 | 19 | public static final Integer NOLOGIN = 20002; 20 | 21 | private Map data = new HashMap(); 22 | 23 | private Result(){}//构造器私有化,使外界无法调用 24 | 25 | public static Result ok(){ 26 | Result r = new Result(); 27 | r.setSuccess(true); 28 | r.setCode(SUCCESS); 29 | r.setMessage("成功"); 30 | return r; 31 | } 32 | 33 | public static Result error(){ 34 | Result r = new Result(); 35 | r.setSuccess(false); 36 | r.setCode(ERROR); 37 | r.setMessage("失败"); 38 | return r; 39 | } 40 | 41 | public Result success(Boolean success){ 42 | this.setSuccess(success); 43 | return this; 44 | } 45 | 46 | public Result message(String message){ 47 | this.setMessage(message); 48 | return this; 49 | } 50 | 51 | public Result code(Integer code){ 52 | this.setCode(code); 53 | return this; 54 | } 55 | 56 | public Result data(String key, Object value){ 57 | this.data.put(key, value); 58 | return this; 59 | } 60 | 61 | public Boolean getSuccess() { 62 | return success; 63 | } 64 | 65 | public void setSuccess(Boolean success) { 66 | this.success = success; 67 | } 68 | 69 | public Integer getCode() { 70 | return code; 71 | } 72 | 73 | public void setCode(Integer code) { 74 | this.code = code; 75 | } 76 | 77 | public String getMessage() { 78 | return message; 79 | } 80 | 81 | public void setMessage(String message) { 82 | this.message = message; 83 | } 84 | 85 | public Map getData() { 86 | return data; 87 | } 88 | 89 | public void setData(Map data) { 90 | this.data = data; 91 | } 92 | 93 | public Result data(Map map){ 94 | this.setData(map); 95 | return this; 96 | } 97 | } -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=NovelTTS 2 | server.port=8000 3 | # ??????? 4 | spring.mvc.view.prefix=classpath:/templates/ 5 | # ??????????? 6 | spring.mvc.view.suffix=.html 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/config.txt: -------------------------------------------------------------------------------- 1 | #Tue Apr 02 11:44:45 CST 2024 2 | batchSize=100 3 | defaultDialogueCharacter=三月七 4 | defaultDialogueEmotion=厌恶 5 | defaultNarrationCharacter=三月七 6 | defaultNarrationEmotion=厌恶 7 | novelPath=E\:\\test\\紫川_原稿 8 | speed=1.0 9 | url=http\://127.0.0.1\:5000/ 10 | -------------------------------------------------------------------------------- /src/main/resources/static/assets/index-BijUbyZy.css: -------------------------------------------------------------------------------- 1 | body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{margin:0;padding:0}ul,ol{list-style:none}img{display:block;border:0}b,strong{font-weight:400}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}i,em{font-style:normal}u,ins,s,del{text-decoration:none}table{border-collapse:collapse;border-spacing:0}input,button,select,textarea{outline:none}a{text-decoration:none;color:inherit}.container[data-v-fba62608]{margin:0 auto;align-items:center;width:1200px;min-width:1200px}select[data-v-fba62608],input[data-v-fba62608]{width:300px;height:30px;margin:10px}button[data-v-fba62608]{width:200px;background-color:#6464c0;height:30px;border-color:#000;border-width:2px}hr[data-v-fba62608]{width:100%;margin-top:10px;margin-bottom:10px}h1[data-v-fba62608]{font-size:45px;margin-top:10px;margin-bottom:20px}table td[data-v-fba62608],th[data-v-fba62608]{padding:5px 80px;text-align:center}.article[data-v-fba62608]{display:flex;flex-direction:column}.item[data-v-fba62608]{display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:space-between;margin-bottom:50px}.sentence[data-v-fba62608]{flex:0 0 70%;margin-right:20px}.info[data-v-fba62608]{flex:0 0 30%}.red-text[data-v-fba62608]{color:red} 2 | -------------------------------------------------------------------------------- /src/main/resources/static/assets/index-DSxEuOva.js: -------------------------------------------------------------------------------- 1 | var ei=Object.defineProperty;var ti=(e,t,n)=>t in e?ei(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Qt=(e,t,n)=>(ti(e,typeof t!="symbol"?t+"":t,n),n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();/** 2 | * @vue/shared v3.4.21 3 | * (c) 2018-present Yuxi (Evan) You and Vue contributors 4 | * @license MIT 5 | **/function ws(e,t){const n=new Set(e.split(","));return t?s=>n.has(s.toLowerCase()):s=>n.has(s)}const ne={},yt=[],Oe=()=>{},ni=()=>!1,Sn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Es=e=>e.startsWith("onUpdate:"),de=Object.assign,xs=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},si=Object.prototype.hasOwnProperty,k=(e,t)=>si.call(e,t),U=Array.isArray,bt=e=>zt(e)==="[object Map]",On=e=>zt(e)==="[object Set]",Ws=e=>zt(e)==="[object Date]",B=e=>typeof e=="function",ue=e=>typeof e=="string",tt=e=>typeof e=="symbol",se=e=>e!==null&&typeof e=="object",Dr=e=>(se(e)||B(e))&&B(e.then)&&B(e.catch),Br=Object.prototype.toString,zt=e=>Br.call(e),ri=e=>zt(e).slice(8,-1),Hr=e=>zt(e)==="[object Object]",Ss=e=>ue(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ut=ws(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Cn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},oi=/-(\w)/g,St=Cn(e=>e.replace(oi,(t,n)=>n?n.toUpperCase():"")),ii=/\B([A-Z])/g,Tt=Cn(e=>e.replace(ii,"-$1").toLowerCase()),Vr=Cn(e=>e.charAt(0).toUpperCase()+e.slice(1)),qn=Cn(e=>e?`on${Vr(e)}`:""),nt=(e,t)=>!Object.is(e,t),on=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Bt=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let Js;const $r=()=>Js||(Js=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Os(e){if(U(e)){const t={};for(let n=0;n{if(n){const s=n.split(ci);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function An(e){let t="";if(ue(e))t=e;else if(U(e))for(let n=0;nTn(n,t))}const ye=e=>ue(e)?e:e==null?"":U(e)||se(e)&&(e.toString===Br||!B(e.toString))?JSON.stringify(e,Kr,2):String(e),Kr=(e,t)=>t&&t.__v_isRef?Kr(e,t.value):bt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],o)=>(n[zn(s,o)+" =>"]=r,n),{})}:On(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>zn(n))}:tt(t)?zn(t):se(t)&&!U(t)&&!Hr(t)?String(t):t,zn=(e,t="")=>{var n;return tt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** 6 | * @vue/reactivity v3.4.21 7 | * (c) 2018-present Yuxi (Evan) You and Vue contributors 8 | * @license MIT 9 | **/let Pe;class mi{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Pe,!t&&Pe&&(this.index=(Pe.scopes||(Pe.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Pe;try{return Pe=this,t()}finally{Pe=n}}}on(){Pe=this}off(){Pe=this.parent}stop(t){if(this._active){let n,s;for(n=0,s=this.effects.length;n=4))break}this._dirtyLevel===1&&(this._dirtyLevel=0),pt()}return this._dirtyLevel>=4}set dirty(t){this._dirtyLevel=t?4:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let t=Ze,n=ft;try{return Ze=!0,ft=this,this._runnings++,Gs(this),this.fn()}finally{Xs(this),this._runnings--,ft=n,Ze=t}}stop(){var t;this.active&&(Gs(this),Xs(this),(t=this.onStop)==null||t.call(this),this.active=!1)}}function yi(e){return e.value}function Gs(e){e._trackId++,e._depsLength=0}function Xs(e){if(e.deps.length>e._depsLength){for(let t=e._depsLength;t{const n=new Map;return n.cleanup=e,n.computed=t,n},is=new WeakMap,at=Symbol(""),ls=Symbol("");function we(e,t,n){if(Ze&&ft){let s=is.get(e);s||is.set(e,s=new Map);let r=s.get(n);r||s.set(n,r=Gr(()=>s.delete(n))),Wr(ft,r)}}function ke(e,t,n,s,r,o){const i=is.get(e);if(!i)return;let l=[];if(t==="clear")l=[...i.values()];else if(n==="length"&&U(e)){const c=Number(s);i.forEach((a,d)=>{(d==="length"||!tt(d)&&d>=c)&&l.push(a)})}else switch(n!==void 0&&l.push(i.get(n)),t){case"add":U(e)?Ss(n)&&l.push(i.get("length")):(l.push(i.get(at)),bt(e)&&l.push(i.get(ls)));break;case"delete":U(e)||(l.push(i.get(at)),bt(e)&&l.push(i.get(ls)));break;case"set":bt(e)&&l.push(i.get(at));break}As();for(const c of l)c&&Jr(c,4);Ts()}const bi=ws("__proto__,__v_isRef,__isVue"),Xr=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(tt)),Ys=wi();function wi(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const s=z(this);for(let o=0,i=this.length;o{e[t]=function(...n){ht(),As();const s=z(this)[t].apply(this,n);return Ts(),pt(),s}}),e}function Ei(e){const t=z(this);return we(t,"has",e),t.hasOwnProperty(e)}class Yr{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){const r=this._isReadonly,o=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return o;if(n==="__v_raw")return s===(r?o?Li:to:o?eo:Zr).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const i=U(t);if(!r){if(i&&k(Ys,n))return Reflect.get(Ys,n,s);if(n==="hasOwnProperty")return Ei}const l=Reflect.get(t,n,s);return(tt(n)?Xr.has(n):bi(n))||(r||we(t,"get",n),o)?l:Y(l)?i&&Ss(n)?l:l.value:se(l)?r?no(l):Ps(l):l}}class Qr extends Yr{constructor(t=!1){super(!1,t)}set(t,n,s,r){let o=t[n];if(!this._isShallow){const c=Ot(o);if(!gn(s)&&!Ot(s)&&(o=z(o),s=z(s)),!U(t)&&Y(o)&&!Y(s))return c?!1:(o.value=s,!0)}const i=U(t)&&Ss(n)?Number(n)e,Rn=e=>Reflect.getPrototypeOf(e);function Zt(e,t,n=!1,s=!1){e=e.__v_raw;const r=z(e),o=z(t);n||(nt(t,o)&&we(r,"get",t),we(r,"get",o));const{has:i}=Rn(r),l=s?Rs:n?Fs:Ht;if(i.call(r,t))return l(e.get(t));if(i.call(r,o))return l(e.get(o));e!==r&&e.get(t)}function en(e,t=!1){const n=this.__v_raw,s=z(n),r=z(e);return t||(nt(e,r)&&we(s,"has",e),we(s,"has",r)),e===r?n.has(e):n.has(e)||n.has(r)}function tn(e,t=!1){return e=e.__v_raw,!t&&we(z(e),"iterate",at),Reflect.get(e,"size",e)}function Qs(e){e=z(e);const t=z(this);return Rn(t).has.call(t,e)||(t.add(e),ke(t,"add",e,e)),this}function Zs(e,t){t=z(t);const n=z(this),{has:s,get:r}=Rn(n);let o=s.call(n,e);o||(e=z(e),o=s.call(n,e));const i=r.call(n,e);return n.set(e,t),o?nt(t,i)&&ke(n,"set",e,t):ke(n,"add",e,t),this}function er(e){const t=z(this),{has:n,get:s}=Rn(t);let r=n.call(t,e);r||(e=z(e),r=n.call(t,e)),s&&s.call(t,e);const o=t.delete(e);return r&&ke(t,"delete",e,void 0),o}function tr(){const e=z(this),t=e.size!==0,n=e.clear();return t&&ke(e,"clear",void 0,void 0),n}function nn(e,t){return function(s,r){const o=this,i=o.__v_raw,l=z(i),c=t?Rs:e?Fs:Ht;return!e&&we(l,"iterate",at),i.forEach((a,d)=>s.call(r,c(a),c(d),o))}}function sn(e,t,n){return function(...s){const r=this.__v_raw,o=z(r),i=bt(o),l=e==="entries"||e===Symbol.iterator&&i,c=e==="keys"&&i,a=r[e](...s),d=n?Rs:t?Fs:Ht;return!t&&we(o,"iterate",c?ls:at),{next(){const{value:h,done:O}=a.next();return O?{value:h,done:O}:{value:l?[d(h[0]),d(h[1])]:d(h),done:O}},[Symbol.iterator](){return this}}}}function We(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Ai(){const e={get(o){return Zt(this,o)},get size(){return tn(this)},has:en,add:Qs,set:Zs,delete:er,clear:tr,forEach:nn(!1,!1)},t={get(o){return Zt(this,o,!1,!0)},get size(){return tn(this)},has:en,add:Qs,set:Zs,delete:er,clear:tr,forEach:nn(!1,!0)},n={get(o){return Zt(this,o,!0)},get size(){return tn(this,!0)},has(o){return en.call(this,o,!0)},add:We("add"),set:We("set"),delete:We("delete"),clear:We("clear"),forEach:nn(!0,!1)},s={get(o){return Zt(this,o,!0,!0)},get size(){return tn(this,!0)},has(o){return en.call(this,o,!0)},add:We("add"),set:We("set"),delete:We("delete"),clear:We("clear"),forEach:nn(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=sn(o,!1,!1),n[o]=sn(o,!0,!1),t[o]=sn(o,!1,!0),s[o]=sn(o,!0,!0)}),[e,n,t,s]}const[Ti,Ri,vi,Pi]=Ai();function vs(e,t){const n=t?e?Pi:vi:e?Ri:Ti;return(s,r,o)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(k(n,r)&&r in s?n:s,r,o)}const Ni={get:vs(!1,!1)},Fi={get:vs(!1,!0)},Ii={get:vs(!0,!1)},Zr=new WeakMap,eo=new WeakMap,to=new WeakMap,Li=new WeakMap;function Ui(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Mi(e){return e.__v_skip||!Object.isExtensible(e)?0:Ui(ri(e))}function Ps(e){return Ot(e)?e:Ns(e,!1,Si,Ni,Zr)}function ji(e){return Ns(e,!1,Ci,Fi,eo)}function no(e){return Ns(e,!0,Oi,Ii,to)}function Ns(e,t,n,s,r){if(!se(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=r.get(e);if(o)return o;const i=Mi(e);if(i===0)return e;const l=new Proxy(e,i===2?s:n);return r.set(e,l),l}function wt(e){return Ot(e)?wt(e.__v_raw):!!(e&&e.__v_isReactive)}function Ot(e){return!!(e&&e.__v_isReadonly)}function gn(e){return!!(e&&e.__v_isShallow)}function so(e){return wt(e)||Ot(e)}function z(e){const t=e&&e.__v_raw;return t?z(t):e}function ro(e){return Object.isExtensible(e)&&mn(e,"__v_skip",!0),e}const Ht=e=>se(e)?Ps(e):e,Fs=e=>se(e)?no(e):e;class oo{constructor(t,n,s,r){this.getter=t,this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new Cs(()=>t(this._value),()=>ln(this,this.effect._dirtyLevel===2?2:3)),this.effect.computed=this,this.effect.active=this._cacheable=!r,this.__v_isReadonly=s}get value(){const t=z(this);return(!t._cacheable||t.effect.dirty)&&nt(t._value,t._value=t.effect.run())&&ln(t,4),io(t),t.effect._dirtyLevel>=2&&ln(t,2),t._value}set value(t){this._setter(t)}get _dirty(){return this.effect.dirty}set _dirty(t){this.effect.dirty=t}}function Di(e,t,n=!1){let s,r;const o=B(e);return o?(s=e,r=Oe):(s=e.get,r=e.set),new oo(s,r,o||!r,n)}function io(e){var t;Ze&&ft&&(e=z(e),Wr(ft,(t=e.dep)!=null?t:e.dep=Gr(()=>e.dep=void 0,e instanceof oo?e:void 0)))}function ln(e,t=4,n){e=z(e);const s=e.dep;s&&Jr(s,t)}function Y(e){return!!(e&&e.__v_isRef===!0)}function Je(e){return Bi(e,!1)}function Bi(e,t){return Y(e)?e:new Hi(e,t)}class Hi{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:z(t),this._value=n?t:Ht(t)}get value(){return io(this),this._value}set value(t){const n=this.__v_isShallow||gn(t)||Ot(t);t=n?t:z(t),nt(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:Ht(t),ln(this,4))}}function te(e){return Y(e)?e.value:e}const Vi={get:(e,t,n)=>te(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return Y(r)&&!Y(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function lo(e){return wt(e)?e:new Proxy(e,Vi)}/** 10 | * @vue/runtime-core v3.4.21 11 | * (c) 2018-present Yuxi (Evan) You and Vue contributors 12 | * @license MIT 13 | **/function et(e,t,n,s){try{return s?e(...s):e()}catch(r){vn(r,t,n)}}function Fe(e,t,n,s){if(B(e)){const o=et(e,t,n,s);return o&&Dr(o)&&o.catch(i=>{vn(i,t,n)}),o}const r=[];for(let o=0;o>>1,r=pe[s],o=$t(r);oMe&&pe.splice(t,1)}function qi(e){U(e)?Et.push(...e):(!Xe||!Xe.includes(e,e.allowRecurse?lt+1:lt))&&Et.push(e),fo()}function nr(e,t,n=Vt?Me+1:0){for(;n$t(n)-$t(s));if(Et.length=0,Xe){Xe.push(...t);return}for(Xe=t,lt=0;lte.id==null?1/0:e.id,zi=(e,t)=>{const n=$t(e)-$t(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function ho(e){cs=!1,Vt=!0,pe.sort(zi);try{for(Me=0;Meue(P)?P.trim():P)),h&&(r=n.map(Bt))}let l,c=s[l=qn(t)]||s[l=qn(St(t))];!c&&o&&(c=s[l=qn(Tt(t))]),c&&Fe(c,e,6,r);const a=s[l+"Once"];if(a){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Fe(a,e,6,r)}}function po(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const o=e.emits;let i={},l=!1;if(!B(e)){const c=a=>{const d=po(a,t,!0);d&&(l=!0,de(i,d))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!o&&!l?(se(e)&&s.set(e,null),null):(U(o)?o.forEach(c=>i[c]=null):de(i,o),se(e)&&s.set(e,i),i)}function Pn(e,t){return!e||!Sn(t)?!1:(t=t.slice(2).replace(/Once$/,""),k(e,t[0].toLowerCase()+t.slice(1))||k(e,Tt(t))||k(e,t))}let xe=null,Nn=null;function _n(e){const t=xe;return xe=e,Nn=e&&e.type.__scopeId||null,t}function Ji(e){Nn=e}function Gi(){Nn=null}function Xi(e,t=xe,n){if(!t||e._n)return e;const s=(...r)=>{s._d&&dr(-1);const o=_n(t);let i;try{i=e(...r)}finally{_n(o),s._d&&dr(1)}return i};return s._n=!0,s._c=!0,s._d=!0,s}function Wn(e){const{type:t,vnode:n,proxy:s,withProxy:r,props:o,propsOptions:[i],slots:l,attrs:c,emit:a,render:d,renderCache:h,data:O,setupState:P,ctx:A,inheritAttrs:x}=e;let j,L;const oe=_n(e);try{if(n.shapeFlag&4){const J=r||s,Q=J;j=Ue(d.call(Q,J,h,o,P,O,A)),L=c}else{const J=t;j=Ue(J.length>1?J(o,{attrs:c,slots:l,emit:a}):J(o,null)),L=t.props?c:Yi(c)}}catch(J){Dt.length=0,vn(J,e,1),j=dt(kt)}let D=j;if(L&&x!==!1){const J=Object.keys(L),{shapeFlag:Q}=D;J.length&&Q&7&&(i&&J.some(Es)&&(L=Qi(L,i)),D=Ct(D,L))}return n.dirs&&(D=Ct(D),D.dirs=D.dirs?D.dirs.concat(n.dirs):n.dirs),n.transition&&(D.transition=n.transition),j=D,_n(oe),j}const Yi=e=>{let t;for(const n in e)(n==="class"||n==="style"||Sn(n))&&((t||(t={}))[n]=e[n]);return t},Qi=(e,t)=>{const n={};for(const s in e)(!Es(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function Zi(e,t,n){const{props:s,children:r,component:o}=e,{props:i,children:l,patchFlag:c}=t,a=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return s?sr(s,i,a):!!i;if(c&8){const d=t.dynamicProps;for(let h=0;he.__isSuspense;function sl(e,t){t&&t.pendingBranch?U(e)?t.effects.push(...e):t.effects.push(e):qi(e)}const rl=Symbol.for("v-scx"),ol=()=>un(rl),rn={};function Jn(e,t,n){return mo(e,t,n)}function mo(e,t,{immediate:n,deep:s,flush:r,once:o,onTrack:i,onTrigger:l}=ne){if(t&&o){const V=t;t=(...Ae)=>{V(...Ae),Q()}}const c=ge,a=V=>s===!0?V:ut(V,s===!1?1:void 0);let d,h=!1,O=!1;if(Y(e)?(d=()=>e.value,h=gn(e)):wt(e)?(d=()=>a(e),h=!0):U(e)?(O=!0,h=e.some(V=>wt(V)||gn(V)),d=()=>e.map(V=>{if(Y(V))return V.value;if(wt(V))return a(V);if(B(V))return et(V,c,2)})):B(e)?t?d=()=>et(e,c,2):d=()=>(P&&P(),Fe(e,c,3,[A])):d=Oe,t&&s){const V=d;d=()=>ut(V())}let P,A=V=>{P=D.onStop=()=>{et(V,c,4),P=D.onStop=void 0}},x;if(Un)if(A=Oe,t?n&&Fe(t,c,3,[d(),O?[]:void 0,A]):d(),r==="sync"){const V=ol();x=V.__watcherHandles||(V.__watcherHandles=[])}else return Oe;let j=O?new Array(e.length).fill(rn):rn;const L=()=>{if(!(!D.active||!D.dirty))if(t){const V=D.run();(s||h||(O?V.some((Ae,Se)=>nt(Ae,j[Se])):nt(V,j)))&&(P&&P(),Fe(t,c,3,[V,j===rn?void 0:O&&j[0]===rn?[]:j,A]),j=V)}else D.run()};L.allowRecurse=!!t;let oe;r==="sync"?oe=L:r==="post"?oe=()=>be(L,c&&c.suspense):(L.pre=!0,c&&(L.id=c.uid),oe=()=>Ls(L));const D=new Cs(d,Oe,oe),J=_i(),Q=()=>{D.stop(),J&&xs(J.effects,D)};return t?n?L():j=D.run():r==="post"?be(D.run.bind(D),c&&c.suspense):D.run(),x&&x.push(Q),Q}function il(e,t,n){const s=this.proxy,r=ue(e)?e.includes(".")?go(s,e):()=>s[e]:e.bind(s,s);let o;B(t)?o=t:(o=t.handler,n=t);const i=Wt(this),l=mo(r,o.bind(s),n);return i(),l}function go(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;r0){if(n>=t)return e;n++}if(s=s||new Set,s.has(e))return e;if(s.add(e),Y(e))ut(e.value,t,n,s);else if(U(e))for(let r=0;r{ut(r,t,n,s)});else if(Hr(e))for(const r in e)ut(e[r],t,n,s);return e}function he(e,t){if(xe===null)return e;const n=Mn(xe)||xe.proxy,s=e.dirs||(e.dirs=[]);for(let r=0;r!!e.type.__asyncLoader,_o=e=>e.type.__isKeepAlive;function cl(e,t){yo(e,"a",t)}function ul(e,t){yo(e,"da",t)}function yo(e,t,n=ge){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(Fn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)_o(r.parent.vnode)&&fl(s,t,n,r),r=r.parent}}function fl(e,t,n,s){const r=Fn(t,e,s,!0);wo(()=>{xs(s[t],r)},n)}function Fn(e,t,n=ge,s=!1){if(n){const r=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{if(n.isUnmounted)return;ht();const l=Wt(n),c=Fe(t,n,e,i);return l(),pt(),c});return s?r.unshift(o):r.push(o),o}}const qe=e=>(t,n=ge)=>(!Un||e==="sp")&&Fn(e,(...s)=>t(...s),n),al=qe("bm"),bo=qe("m"),dl=qe("bu"),hl=qe("u"),pl=qe("bum"),wo=qe("um"),ml=qe("sp"),gl=qe("rtg"),_l=qe("rtc");function yl(e,t=ge){Fn("ec",e,t)}function ve(e,t,n,s){let r;const o=n&&n[s];if(U(e)||ue(e)){r=new Array(e.length);for(let i=0,l=e.length;it(i,l,void 0,o&&o[l]));else{const i=Object.keys(e);r=new Array(i.length);for(let l=0,c=i.length;le?No(e)?Mn(e)||e.proxy:us(e.parent):null,Mt=de(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>us(e.parent),$root:e=>us(e.root),$emit:e=>e.emit,$options:e=>Us(e),$forceUpdate:e=>e.f||(e.f=()=>{e.effect.dirty=!0,Ls(e.update)}),$nextTick:e=>e.n||(e.n=uo.bind(e.proxy)),$watch:e=>il.bind(e)}),Gn=(e,t)=>e!==ne&&!e.__isScriptSetup&&k(e,t),bl={get({_:e},t){const{ctx:n,setupState:s,data:r,props:o,accessCache:i,type:l,appContext:c}=e;let a;if(t[0]!=="$"){const P=i[t];if(P!==void 0)switch(P){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return o[t]}else{if(Gn(s,t))return i[t]=1,s[t];if(r!==ne&&k(r,t))return i[t]=2,r[t];if((a=e.propsOptions[0])&&k(a,t))return i[t]=3,o[t];if(n!==ne&&k(n,t))return i[t]=4,n[t];fs&&(i[t]=0)}}const d=Mt[t];let h,O;if(d)return t==="$attrs"&&we(e,"get",t),d(e);if((h=l.__cssModules)&&(h=h[t]))return h;if(n!==ne&&k(n,t))return i[t]=4,n[t];if(O=c.config.globalProperties,k(O,t))return O[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:o}=e;return Gn(r,t)?(r[t]=n,!0):s!==ne&&k(s,t)?(s[t]=n,!0):k(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:o}},i){let l;return!!n[i]||e!==ne&&k(e,i)||Gn(t,i)||(l=o[0])&&k(l,i)||k(s,i)||k(Mt,i)||k(r.config.globalProperties,i)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:k(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function rr(e){return U(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let fs=!0;function wl(e){const t=Us(e),n=e.proxy,s=e.ctx;fs=!1,t.beforeCreate&&or(t.beforeCreate,e,"bc");const{data:r,computed:o,methods:i,watch:l,provide:c,inject:a,created:d,beforeMount:h,mounted:O,beforeUpdate:P,updated:A,activated:x,deactivated:j,beforeDestroy:L,beforeUnmount:oe,destroyed:D,unmounted:J,render:Q,renderTracked:V,renderTriggered:Ae,errorCaptured:Se,serverPrefetch:vt,expose:Be,inheritAttrs:ze,components:st,directives:mt,filters:Pt}=t;if(a&&El(a,s,null),i)for(const Z in i){const G=i[Z];B(G)&&(s[Z]=G.bind(n))}if(r){const Z=r.call(n,n);se(Z)&&(e.data=Ps(Z))}if(fs=!0,o)for(const Z in o){const G=o[Z],He=B(G)?G.bind(n,n):B(G.get)?G.get.bind(n,n):Oe,gt=!B(G)&&B(G.set)?G.set.bind(n):Oe,Ve=Zl({get:He,set:gt});Object.defineProperty(s,Z,{enumerable:!0,configurable:!0,get:()=>Ve.value,set:_e=>Ve.value=_e})}if(l)for(const Z in l)Eo(l[Z],s,n,Z);if(c){const Z=B(c)?c.call(n):c;Reflect.ownKeys(Z).forEach(G=>{Tl(G,Z[G])})}d&&or(d,e,"c");function ae(Z,G){U(G)?G.forEach(He=>Z(He.bind(n))):G&&Z(G.bind(n))}if(ae(al,h),ae(bo,O),ae(dl,P),ae(hl,A),ae(cl,x),ae(ul,j),ae(yl,Se),ae(_l,V),ae(gl,Ae),ae(pl,oe),ae(wo,J),ae(ml,vt),U(Be))if(Be.length){const Z=e.exposed||(e.exposed={});Be.forEach(G=>{Object.defineProperty(Z,G,{get:()=>n[G],set:He=>n[G]=He})})}else e.exposed||(e.exposed={});Q&&e.render===Oe&&(e.render=Q),ze!=null&&(e.inheritAttrs=ze),st&&(e.components=st),mt&&(e.directives=mt)}function El(e,t,n=Oe){U(e)&&(e=as(e));for(const s in e){const r=e[s];let o;se(r)?"default"in r?o=un(r.from||s,r.default,!0):o=un(r.from||s):o=un(r),Y(o)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[s]=o}}function or(e,t,n){Fe(U(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Eo(e,t,n,s){const r=s.includes(".")?go(n,s):()=>n[s];if(ue(e)){const o=t[e];B(o)&&Jn(r,o)}else if(B(e))Jn(r,e.bind(n));else if(se(e))if(U(e))e.forEach(o=>Eo(o,t,n,s));else{const o=B(e.handler)?e.handler.bind(n):t[e.handler];B(o)&&Jn(r,o,e)}}function Us(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let c;return l?c=l:!r.length&&!n&&!s?c=t:(c={},r.length&&r.forEach(a=>yn(c,a,i,!0)),yn(c,t,i)),se(t)&&o.set(t,c),c}function yn(e,t,n,s=!1){const{mixins:r,extends:o}=t;o&&yn(e,o,n,!0),r&&r.forEach(i=>yn(e,i,n,!0));for(const i in t)if(!(s&&i==="expose")){const l=xl[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const xl={data:ir,props:lr,emits:lr,methods:Lt,computed:Lt,beforeCreate:me,created:me,beforeMount:me,mounted:me,beforeUpdate:me,updated:me,beforeDestroy:me,beforeUnmount:me,destroyed:me,unmounted:me,activated:me,deactivated:me,errorCaptured:me,serverPrefetch:me,components:Lt,directives:Lt,watch:Ol,provide:ir,inject:Sl};function ir(e,t){return t?e?function(){return de(B(e)?e.call(this,this):e,B(t)?t.call(this,this):t)}:t:e}function Sl(e,t){return Lt(as(e),as(t))}function as(e){if(U(e)){const t={};for(let n=0;n1)return n&&B(t)?t.call(s&&s.proxy):t}}function Rl(e,t,n,s=!1){const r={},o={};mn(o,Ln,1),e.propsDefaults=Object.create(null),So(e,t,r,o);for(const i in e.propsOptions[0])i in r||(r[i]=void 0);n?e.props=s?r:ji(r):e.type.props?e.props=r:e.props=o,e.attrs=o}function vl(e,t,n,s){const{props:r,attrs:o,vnode:{patchFlag:i}}=e,l=z(r),[c]=e.propsOptions;let a=!1;if((s||i>0)&&!(i&16)){if(i&8){const d=e.vnode.dynamicProps;for(let h=0;h{c=!0;const[O,P]=Oo(h,t,!0);de(i,O),P&&l.push(...P)};!n&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!o&&!c)return se(e)&&s.set(e,yt),yt;if(U(o))for(let d=0;d-1,P[1]=x<0||A-1||k(P,"default"))&&l.push(h)}}}const a=[i,l];return se(e)&&s.set(e,a),a}function cr(e){return e[0]!=="$"&&!Ut(e)}function ur(e){return e===null?"null":typeof e=="function"?e.name||"":typeof e=="object"&&e.constructor&&e.constructor.name||""}function fr(e,t){return ur(e)===ur(t)}function ar(e,t){return U(t)?t.findIndex(n=>fr(n,e)):B(t)&&fr(t,e)?0:-1}const Co=e=>e[0]==="_"||e==="$stable",Ms=e=>U(e)?e.map(Ue):[Ue(e)],Pl=(e,t,n)=>{if(t._n)return t;const s=Xi((...r)=>Ms(t(...r)),n);return s._c=!1,s},Ao=(e,t,n)=>{const s=e._ctx;for(const r in e){if(Co(r))continue;const o=e[r];if(B(o))t[r]=Pl(r,o,s);else if(o!=null){const i=Ms(o);t[r]=()=>i}}},To=(e,t)=>{const n=Ms(t);e.slots.default=()=>n},Nl=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=z(t),mn(t,"_",n)):Ao(t,e.slots={})}else e.slots={},t&&To(e,t);mn(e.slots,Ln,1)},Fl=(e,t,n)=>{const{vnode:s,slots:r}=e;let o=!0,i=ne;if(s.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:(de(r,t),!n&&l===1&&delete r._):(o=!t.$stable,Ao(t,r)),i=t}else t&&(To(e,t),i={default:1});if(o)for(const l in r)!Co(l)&&i[l]==null&&delete r[l]};function hs(e,t,n,s,r=!1){if(U(e)){e.forEach((O,P)=>hs(O,t&&(U(t)?t[P]:t),n,s,r));return}if(cn(s)&&!r)return;const o=s.shapeFlag&4?Mn(s.component)||s.component.proxy:s.el,i=r?null:o,{i:l,r:c}=e,a=t&&t.r,d=l.refs===ne?l.refs={}:l.refs,h=l.setupState;if(a!=null&&a!==c&&(ue(a)?(d[a]=null,k(h,a)&&(h[a]=null)):Y(a)&&(a.value=null)),B(c))et(c,l,12,[i,d]);else{const O=ue(c),P=Y(c);if(O||P){const A=()=>{if(e.f){const x=O?k(h,c)?h[c]:d[c]:c.value;r?U(x)&&xs(x,o):U(x)?x.includes(o)||x.push(o):O?(d[c]=[o],k(h,c)&&(h[c]=d[c])):(c.value=[o],e.k&&(d[e.k]=c.value))}else O?(d[c]=i,k(h,c)&&(h[c]=i)):P&&(c.value=i,e.k&&(d[e.k]=i))};i?(A.id=-1,be(A,n)):A()}}}const be=sl;function Il(e){return Ll(e)}function Ll(e,t){const n=$r();n.__VUE__=!0;const{insert:s,remove:r,patchProp:o,createElement:i,createText:l,createComment:c,setText:a,setElementText:d,parentNode:h,nextSibling:O,setScopeId:P=Oe,insertStaticContent:A}=e,x=(u,f,p,g=null,_=null,S=null,T=void 0,w=null,C=!!f.dynamicChildren)=>{if(u===f)return;u&&!Ft(u,f)&&(g=F(u),_e(u,_,S,!0),u=null),f.patchFlag===-2&&(C=!1,f.dynamicChildren=null);const{type:b,ref:R,shapeFlag:I}=f;switch(b){case In:j(u,f,p,g);break;case kt:L(u,f,p,g);break;case Yn:u==null&&oe(f,p,g,T);break;case ce:st(u,f,p,g,_,S,T,w,C);break;default:I&1?Q(u,f,p,g,_,S,T,w,C):I&6?mt(u,f,p,g,_,S,T,w,C):(I&64||I&128)&&b.process(u,f,p,g,_,S,T,w,C,K)}R!=null&&_&&hs(R,u&&u.ref,S,f||u,!f)},j=(u,f,p,g)=>{if(u==null)s(f.el=l(f.children),p,g);else{const _=f.el=u.el;f.children!==u.children&&a(_,f.children)}},L=(u,f,p,g)=>{u==null?s(f.el=c(f.children||""),p,g):f.el=u.el},oe=(u,f,p,g)=>{[u.el,u.anchor]=A(u.children,f,p,g,u.el,u.anchor)},D=({el:u,anchor:f},p,g)=>{let _;for(;u&&u!==f;)_=O(u),s(u,p,g),u=_;s(f,p,g)},J=({el:u,anchor:f})=>{let p;for(;u&&u!==f;)p=O(u),r(u),u=p;r(f)},Q=(u,f,p,g,_,S,T,w,C)=>{f.type==="svg"?T="svg":f.type==="math"&&(T="mathml"),u==null?V(f,p,g,_,S,T,w,C):vt(u,f,_,S,T,w,C)},V=(u,f,p,g,_,S,T,w)=>{let C,b;const{props:R,shapeFlag:I,transition:N,dirs:M}=u;if(C=u.el=i(u.type,S,R&&R.is,R),I&8?d(C,u.children):I&16&&Se(u.children,C,null,g,_,Xn(u,S),T,w),M&&rt(u,null,g,"created"),Ae(C,u,u.scopeId,T,g),R){for(const X in R)X!=="value"&&!Ut(X)&&o(C,X,null,R[X],S,u.children,g,_,Te);"value"in R&&o(C,"value",null,R.value,S),(b=R.onVnodeBeforeMount)&&Le(b,g,u)}M&&rt(u,null,g,"beforeMount");const H=Ul(_,N);H&&N.beforeEnter(C),s(C,f,p),((b=R&&R.onVnodeMounted)||H||M)&&be(()=>{b&&Le(b,g,u),H&&N.enter(C),M&&rt(u,null,g,"mounted")},_)},Ae=(u,f,p,g,_)=>{if(p&&P(u,p),g)for(let S=0;S{for(let b=C;b{const w=f.el=u.el;let{patchFlag:C,dynamicChildren:b,dirs:R}=f;C|=u.patchFlag&16;const I=u.props||ne,N=f.props||ne;let M;if(p&&ot(p,!1),(M=N.onVnodeBeforeUpdate)&&Le(M,p,f,u),R&&rt(f,u,p,"beforeUpdate"),p&&ot(p,!0),b?Be(u.dynamicChildren,b,w,p,g,Xn(f,_),S):T||G(u,f,w,null,p,g,Xn(f,_),S,!1),C>0){if(C&16)ze(w,f,I,N,p,g,_);else if(C&2&&I.class!==N.class&&o(w,"class",null,N.class,_),C&4&&o(w,"style",I.style,N.style,_),C&8){const H=f.dynamicProps;for(let X=0;X{M&&Le(M,p,f,u),R&&rt(f,u,p,"updated")},g)},Be=(u,f,p,g,_,S,T)=>{for(let w=0;w{if(p!==g){if(p!==ne)for(const w in p)!Ut(w)&&!(w in g)&&o(u,w,p[w],null,T,f.children,_,S,Te);for(const w in g){if(Ut(w))continue;const C=g[w],b=p[w];C!==b&&w!=="value"&&o(u,w,b,C,T,f.children,_,S,Te)}"value"in g&&o(u,"value",p.value,g.value,T)}},st=(u,f,p,g,_,S,T,w,C)=>{const b=f.el=u?u.el:l(""),R=f.anchor=u?u.anchor:l("");let{patchFlag:I,dynamicChildren:N,slotScopeIds:M}=f;M&&(w=w?w.concat(M):M),u==null?(s(b,p,g),s(R,p,g),Se(f.children||[],p,R,_,S,T,w,C)):I>0&&I&64&&N&&u.dynamicChildren?(Be(u.dynamicChildren,N,p,_,S,T,w),(f.key!=null||_&&f===_.subTree)&&Ro(u,f,!0)):G(u,f,p,R,_,S,T,w,C)},mt=(u,f,p,g,_,S,T,w,C)=>{f.slotScopeIds=w,u==null?f.shapeFlag&512?_.ctx.activate(f,p,g,T,C):Pt(f,p,g,_,S,T,C):Xt(u,f,C)},Pt=(u,f,p,g,_,S,T)=>{const w=u.component=Wl(u,g,_);if(_o(u)&&(w.ctx.renderer=K),Jl(w),w.asyncDep){if(_&&_.registerDep(w,ae),!u.el){const C=w.subTree=dt(kt);L(null,C,f,p)}}else ae(w,u,f,p,_,S,T)},Xt=(u,f,p)=>{const g=f.component=u.component;if(Zi(u,f,p))if(g.asyncDep&&!g.asyncResolved){Z(g,f,p);return}else g.next=f,Ki(g.update),g.effect.dirty=!0,g.update();else f.el=u.el,g.vnode=f},ae=(u,f,p,g,_,S,T)=>{const w=()=>{if(u.isMounted){let{next:R,bu:I,u:N,parent:M,vnode:H}=u;{const _t=vo(u);if(_t){R&&(R.el=H.el,Z(u,R,T)),_t.asyncDep.then(()=>{u.isUnmounted||w()});return}}let X=R,re;ot(u,!1),R?(R.el=H.el,Z(u,R,T)):R=H,I&&on(I),(re=R.props&&R.props.onVnodeBeforeUpdate)&&Le(re,M,R,H),ot(u,!0);const fe=Wn(u),Re=u.subTree;u.subTree=fe,x(Re,fe,h(Re.el),F(Re),u,_,S),R.el=fe.el,X===null&&el(u,fe.el),N&&be(N,_),(re=R.props&&R.props.onVnodeUpdated)&&be(()=>Le(re,M,R,H),_)}else{let R;const{el:I,props:N}=f,{bm:M,m:H,parent:X}=u,re=cn(f);if(ot(u,!1),M&&on(M),!re&&(R=N&&N.onVnodeBeforeMount)&&Le(R,X,f),ot(u,!0),I&&Kn){const fe=()=>{u.subTree=Wn(u),Kn(I,u.subTree,u,_,null)};re?f.type.__asyncLoader().then(()=>!u.isUnmounted&&fe()):fe()}else{const fe=u.subTree=Wn(u);x(null,fe,p,g,u,_,S),f.el=fe.el}if(H&&be(H,_),!re&&(R=N&&N.onVnodeMounted)){const fe=f;be(()=>Le(R,X,fe),_)}(f.shapeFlag&256||X&&cn(X.vnode)&&X.vnode.shapeFlag&256)&&u.a&&be(u.a,_),u.isMounted=!0,f=p=g=null}},C=u.effect=new Cs(w,Oe,()=>Ls(b),u.scope),b=u.update=()=>{C.dirty&&C.run()};b.id=u.uid,ot(u,!0),b()},Z=(u,f,p)=>{f.component=u;const g=u.vnode.props;u.vnode=f,u.next=null,vl(u,f.props,g,p),Fl(u,f.children,p),ht(),nr(u),pt()},G=(u,f,p,g,_,S,T,w,C=!1)=>{const b=u&&u.children,R=u?u.shapeFlag:0,I=f.children,{patchFlag:N,shapeFlag:M}=f;if(N>0){if(N&128){gt(b,I,p,g,_,S,T,w,C);return}else if(N&256){He(b,I,p,g,_,S,T,w,C);return}}M&8?(R&16&&Te(b,_,S),I!==b&&d(p,I)):R&16?M&16?gt(b,I,p,g,_,S,T,w,C):Te(b,_,S,!0):(R&8&&d(p,""),M&16&&Se(I,p,g,_,S,T,w,C))},He=(u,f,p,g,_,S,T,w,C)=>{u=u||yt,f=f||yt;const b=u.length,R=f.length,I=Math.min(b,R);let N;for(N=0;NR?Te(u,_,S,!0,!1,I):Se(f,p,g,_,S,T,w,C,I)},gt=(u,f,p,g,_,S,T,w,C)=>{let b=0;const R=f.length;let I=u.length-1,N=R-1;for(;b<=I&&b<=N;){const M=u[b],H=f[b]=C?Ye(f[b]):Ue(f[b]);if(Ft(M,H))x(M,H,p,null,_,S,T,w,C);else break;b++}for(;b<=I&&b<=N;){const M=u[I],H=f[N]=C?Ye(f[N]):Ue(f[N]);if(Ft(M,H))x(M,H,p,null,_,S,T,w,C);else break;I--,N--}if(b>I){if(b<=N){const M=N+1,H=MN)for(;b<=I;)_e(u[b],_,S,!0),b++;else{const M=b,H=b,X=new Map;for(b=H;b<=N;b++){const Ee=f[b]=C?Ye(f[b]):Ue(f[b]);Ee.key!=null&&X.set(Ee.key,b)}let re,fe=0;const Re=N-H+1;let _t=!1,Ks=0;const Nt=new Array(Re);for(b=0;b=Re){_e(Ee,_,S,!0);continue}let Ie;if(Ee.key!=null)Ie=X.get(Ee.key);else for(re=H;re<=N;re++)if(Nt[re-H]===0&&Ft(Ee,f[re])){Ie=re;break}Ie===void 0?_e(Ee,_,S,!0):(Nt[Ie-H]=b+1,Ie>=Ks?Ks=Ie:_t=!0,x(Ee,f[Ie],p,null,_,S,T,w,C),fe++)}const qs=_t?Ml(Nt):yt;for(re=qs.length-1,b=Re-1;b>=0;b--){const Ee=H+b,Ie=f[Ee],zs=Ee+1{const{el:S,type:T,transition:w,children:C,shapeFlag:b}=u;if(b&6){Ve(u.component.subTree,f,p,g);return}if(b&128){u.suspense.move(f,p,g);return}if(b&64){T.move(u,f,p,K);return}if(T===ce){s(S,f,p);for(let I=0;Iw.enter(S),_);else{const{leave:I,delayLeave:N,afterLeave:M}=w,H=()=>s(S,f,p),X=()=>{I(S,()=>{H(),M&&M()})};N?N(S,H,X):X()}else s(S,f,p)},_e=(u,f,p,g=!1,_=!1)=>{const{type:S,props:T,ref:w,children:C,dynamicChildren:b,shapeFlag:R,patchFlag:I,dirs:N}=u;if(w!=null&&hs(w,null,p,u,!0),R&256){f.ctx.deactivate(u);return}const M=R&1&&N,H=!cn(u);let X;if(H&&(X=T&&T.onVnodeBeforeUnmount)&&Le(X,f,u),R&6)kn(u.component,p,g);else{if(R&128){u.suspense.unmount(p,g);return}M&&rt(u,null,f,"beforeUnmount"),R&64?u.type.remove(u,f,p,_,K,g):b&&(S!==ce||I>0&&I&64)?Te(b,f,p,!1,!0):(S===ce&&I&384||!_&&R&16)&&Te(C,f,p),g&&Yt(u)}(H&&(X=T&&T.onVnodeUnmounted)||M)&&be(()=>{X&&Le(X,f,u),M&&rt(u,null,f,"unmounted")},p)},Yt=u=>{const{type:f,el:p,anchor:g,transition:_}=u;if(f===ce){$n(p,g);return}if(f===Yn){J(u);return}const S=()=>{r(p),_&&!_.persisted&&_.afterLeave&&_.afterLeave()};if(u.shapeFlag&1&&_&&!_.persisted){const{leave:T,delayLeave:w}=_,C=()=>T(p,S);w?w(u.el,S,C):C()}else S()},$n=(u,f)=>{let p;for(;u!==f;)p=O(u),r(u),u=p;r(f)},kn=(u,f,p)=>{const{bum:g,scope:_,update:S,subTree:T,um:w}=u;g&&on(g),_.stop(),S&&(S.active=!1,_e(T,u,f,p)),w&&be(w,f),be(()=>{u.isUnmounted=!0},f),f&&f.pendingBranch&&!f.isUnmounted&&u.asyncDep&&!u.asyncResolved&&u.suspenseId===f.pendingId&&(f.deps--,f.deps===0&&f.resolve())},Te=(u,f,p,g=!1,_=!1,S=0)=>{for(let T=S;Tu.shapeFlag&6?F(u.component.subTree):u.shapeFlag&128?u.suspense.next():O(u.anchor||u.el);let v=!1;const y=(u,f,p)=>{u==null?f._vnode&&_e(f._vnode,null,null,!0):x(f._vnode||null,u,f,null,null,null,p),v||(v=!0,nr(),ao(),v=!1),f._vnode=u},K={p:x,um:_e,m:Ve,r:Yt,mt:Pt,mc:Se,pc:G,pbc:Be,n:F,o:e};let ee,Kn;return t&&([ee,Kn]=t(K)),{render:y,hydrate:ee,createApp:Al(y,ee)}}function Xn({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function ot({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function Ul(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Ro(e,t,n=!1){const s=e.children,r=t.children;if(U(s)&&U(r))for(let o=0;o>1,e[n[l]]0&&(t[s]=n[o-1]),n[o]=s)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}function vo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:vo(t)}const jl=e=>e.__isTeleport,ce=Symbol.for("v-fgt"),In=Symbol.for("v-txt"),kt=Symbol.for("v-cmt"),Yn=Symbol.for("v-stc"),Dt=[];let Ne=null;function ie(e=!1){Dt.push(Ne=e?null:[])}function Dl(){Dt.pop(),Ne=Dt[Dt.length-1]||null}let Kt=1;function dr(e){Kt+=e}function Bl(e){return e.dynamicChildren=Kt>0?Ne||yt:null,Dl(),Kt>0&&Ne&&Ne.push(e),e}function le(e,t,n,s,r,o){return Bl(E(e,t,n,s,r,o,!0))}function Hl(e){return e?e.__v_isVNode===!0:!1}function Ft(e,t){return e.type===t.type&&e.key===t.key}const Ln="__vInternal",Po=({key:e})=>e??null,fn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?ue(e)||Y(e)||B(e)?{i:xe,r:e,k:t,f:!!n}:e:null);function E(e,t=null,n=null,s=0,r=null,o=e===ce?0:1,i=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Po(t),ref:t&&fn(t),scopeId:Nn,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:xe};return l?(js(c,n),o&128&&e.normalize(c)):n&&(c.shapeFlag|=ue(n)?8:16),Kt>0&&!i&&Ne&&(c.patchFlag>0||o&6)&&c.patchFlag!==32&&Ne.push(c),c}const dt=Vl;function Vl(e,t=null,n=null,s=0,r=null,o=!1){if((!e||e===tl)&&(e=kt),Hl(e)){const l=Ct(e,t,!0);return n&&js(l,n),Kt>0&&!o&&Ne&&(l.shapeFlag&6?Ne[Ne.indexOf(e)]=l:Ne.push(l)),l.patchFlag|=-2,l}if(Ql(e)&&(e=e.__vccOpts),t){t=$l(t);let{class:l,style:c}=t;l&&!ue(l)&&(t.class=An(l)),se(c)&&(so(c)&&!U(c)&&(c=de({},c)),t.style=Os(c))}const i=ue(e)?1:nl(e)?128:jl(e)?64:se(e)?4:B(e)?2:0;return E(e,t,n,s,r,i,o,!0)}function $l(e){return e?so(e)||Ln in e?de({},e):e:null}function Ct(e,t,n=!1){const{props:s,ref:r,patchFlag:o,children:i}=e,l=t?Kl(s||{},t):s;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Po(l),ref:t&&t.ref?n&&r?U(r)?r.concat(fn(t)):[r,fn(t)]:fn(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ce?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ct(e.ssContent),ssFallback:e.ssFallback&&Ct(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function kl(e=" ",t=0){return dt(In,null,e,t)}function Ue(e){return e==null||typeof e=="boolean"?dt(kt):U(e)?dt(ce,null,e.slice()):typeof e=="object"?Ye(e):dt(In,null,String(e))}function Ye(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Ct(e)}function js(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(U(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),js(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!(Ln in t)?t._ctx=xe:r===3&&xe&&(xe.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else B(t)?(t={default:t,_ctx:xe},n=32):(t=String(t),s&64?(n=16,t=[kl(t)]):n=8);e.children=t,e.shapeFlag|=n}function Kl(...e){const t={};for(let n=0;n{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),o=>{r.length>1?r.forEach(i=>i(o)):r[0](o)}};bn=t("__VUE_INSTANCE_SETTERS__",n=>ge=n),ps=t("__VUE_SSR_SETTERS__",n=>Un=n)}const Wt=e=>{const t=ge;return bn(e),e.scope.on(),()=>{e.scope.off(),bn(t)}},hr=()=>{ge&&ge.scope.off(),bn(null)};function No(e){return e.vnode.shapeFlag&4}let Un=!1;function Jl(e,t=!1){t&&ps(t);const{props:n,children:s}=e.vnode,r=No(e);Rl(e,n,r,t),Nl(e,s);const o=r?Gl(e,t):void 0;return t&&ps(!1),o}function Gl(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=ro(new Proxy(e.ctx,bl));const{setup:s}=n;if(s){const r=e.setupContext=s.length>1?Yl(e):null,o=Wt(e);ht();const i=et(s,e,0,[e.props,r]);if(pt(),o(),Dr(i)){if(i.then(hr,hr),t)return i.then(l=>{pr(e,l,t)}).catch(l=>{vn(l,e,0)});e.asyncDep=i}else pr(e,i,t)}else Fo(e,t)}function pr(e,t,n){B(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:se(t)&&(e.setupState=lo(t)),Fo(e,n)}let mr;function Fo(e,t,n){const s=e.type;if(!e.render){if(!t&&mr&&!s.render){const r=s.template||Us(e).template;if(r){const{isCustomElement:o,compilerOptions:i}=e.appContext.config,{delimiters:l,compilerOptions:c}=s,a=de(de({isCustomElement:o,delimiters:l},i),c);s.render=mr(r,a)}}e.render=s.render||Oe}{const r=Wt(e);ht();try{wl(e)}finally{pt(),r()}}}function Xl(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return we(e,"get","$attrs"),t[n]}}))}function Yl(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return Xl(e)},slots:e.slots,emit:e.emit,expose:t}}function Mn(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(lo(ro(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Mt)return Mt[n](e)},has(t,n){return n in t||n in Mt}}))}function Ql(e){return B(e)&&"__vccOpts"in e}const Zl=(e,t)=>Di(e,t,Un),ec="3.4.21";/** 14 | * @vue/runtime-dom v3.4.21 15 | * (c) 2018-present Yuxi (Evan) You and Vue contributors 16 | * @license MIT 17 | **/const tc="http://www.w3.org/2000/svg",nc="http://www.w3.org/1998/Math/MathML",Qe=typeof document<"u"?document:null,gr=Qe&&Qe.createElement("template"),sc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?Qe.createElementNS(tc,e):t==="mathml"?Qe.createElementNS(nc,e):Qe.createElement(e,n?{is:n}:void 0);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>Qe.createTextNode(e),createComment:e=>Qe.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Qe.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,o){const i=n?n.previousSibling:t.lastChild;if(r&&(r===o||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===o||!(r=r.nextSibling)););else{gr.innerHTML=s==="svg"?`${e}`:s==="mathml"?`${e}`:e;const l=gr.content;if(s==="svg"||s==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},rc=Symbol("_vtc");function oc(e,t,n){const s=e[rc];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const _r=Symbol("_vod"),ic=Symbol("_vsh"),lc=Symbol(""),cc=/(^|;)\s*display\s*:/;function uc(e,t,n){const s=e.style,r=ue(n);let o=!1;if(n&&!r){if(t)if(ue(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&an(s,l,"")}else for(const i in t)n[i]==null&&an(s,i,"");for(const i in n)i==="display"&&(o=!0),an(s,i,n[i])}else if(r){if(t!==n){const i=s[lc];i&&(n+=";"+i),s.cssText=n,o=cc.test(n)}}else t&&e.removeAttribute("style");_r in e&&(e[_r]=o?s.display:"",e[ic]&&(s.display="none"))}const yr=/\s*!important$/;function an(e,t,n){if(U(n))n.forEach(s=>an(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=fc(e,t);yr.test(n)?e.setProperty(Tt(s),n.replace(yr,""),"important"):e[s]=n}}const br=["Webkit","Moz","ms"],Qn={};function fc(e,t){const n=Qn[t];if(n)return n;let s=St(t);if(s!=="filter"&&s in e)return Qn[t]=s;s=Vr(s);for(let r=0;rZn||(gc.then(()=>Zn=0),Zn=Date.now());function yc(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;Fe(bc(s,n.value),t,5,[s])};return n.value=e,n.attached=_c(),n}function bc(e,t){if(U(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const Sr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,wc=(e,t,n,s,r,o,i,l,c)=>{const a=r==="svg";t==="class"?oc(e,s,a):t==="style"?uc(e,n,s):Sn(t)?Es(t)||pc(e,t,n,s,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ec(e,t,s,a))?dc(e,t,s,o,i,l,c):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),ac(e,t,s,a))};function Ec(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&Sr(t)&&B(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return Sr(t)&&ue(n)?!1:t in e}const wn=e=>{const t=e.props["onUpdate:modelValue"]||!1;return U(t)?n=>on(t,n):t};function xc(e){e.target.composing=!0}function Or(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const xt=Symbol("_assign"),it={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[xt]=wn(r);const o=s||r.props&&r.props.type==="number";ct(e,t?"change":"input",i=>{if(i.target.composing)return;let l=e.value;n&&(l=l.trim()),o&&(l=Bt(l)),e[xt](l)}),n&&ct(e,"change",()=>{e.value=e.value.trim()}),t||(ct(e,"compositionstart",xc),ct(e,"compositionend",Or),ct(e,"change",Or))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:s,number:r}},o){if(e[xt]=wn(o),e.composing)return;const i=r||e.type==="number"?Bt(e.value):e.value,l=t??"";i!==l&&(document.activeElement===e&&e.type!=="range"&&(n||s&&e.value.trim()===l)||(e.value=l))}},$e={deep:!0,created(e,{value:t,modifiers:{number:n}},s){const r=On(t);ct(e,"change",()=>{const o=Array.prototype.filter.call(e.options,i=>i.selected).map(i=>n?Bt(En(i)):En(i));e[xt](e.multiple?r?new Set(o):o:o[0]),e._assigning=!0,uo(()=>{e._assigning=!1})}),e[xt]=wn(s)},mounted(e,{value:t,modifiers:{number:n}}){Cr(e,t,n)},beforeUpdate(e,t,n){e[xt]=wn(n)},updated(e,{value:t,modifiers:{number:n}}){e._assigning||Cr(e,t,n)}};function Cr(e,t,n){const s=e.multiple,r=U(t);if(!(s&&!r&&!On(t))){for(let o=0,i=e.options.length;o-1}else l.selected=t.has(c);else if(Tn(En(l),t)){e.selectedIndex!==o&&(e.selectedIndex=o);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function En(e){return"_value"in e?e._value:e.value}const Sc=de({patchProp:wc},sc);let Ar;function Oc(){return Ar||(Ar=Il(Sc))}const Cc=(...e)=>{const t=Oc().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Tc(s);if(!r)return;const o=t._component;!B(o)&&!o.render&&!o.template&&(o.template=r.innerHTML),r.innerHTML="";const i=n(r,!1,Ac(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),i},t};function Ac(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Tc(e){return ue(e)?document.querySelector(e):e}function Io(e,t){return function(){return e.apply(t,arguments)}}const{toString:Rc}=Object.prototype,{getPrototypeOf:Ds}=Object,jn=(e=>t=>{const n=Rc.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),De=e=>(e=e.toLowerCase(),t=>jn(t)===e),Dn=e=>t=>typeof t===e,{isArray:Rt}=Array,qt=Dn("undefined");function vc(e){return e!==null&&!qt(e)&&e.constructor!==null&&!qt(e.constructor)&&Ce(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const Lo=De("ArrayBuffer");function Pc(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Lo(e.buffer),t}const Nc=Dn("string"),Ce=Dn("function"),Uo=Dn("number"),Bn=e=>e!==null&&typeof e=="object",Fc=e=>e===!0||e===!1,dn=e=>{if(jn(e)!=="object")return!1;const t=Ds(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)},Ic=De("Date"),Lc=De("File"),Uc=De("Blob"),Mc=De("FileList"),jc=e=>Bn(e)&&Ce(e.pipe),Dc=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||Ce(e.append)&&((t=jn(e))==="formdata"||t==="object"&&Ce(e.toString)&&e.toString()==="[object FormData]"))},Bc=De("URLSearchParams"),Hc=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function Jt(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let s,r;if(typeof e!="object"&&(e=[e]),Rt(e))for(s=0,r=e.length;s0;)if(r=n[s],t===r.toLowerCase())return r;return null}const jo=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,Do=e=>!qt(e)&&e!==jo;function ms(){const{caseless:e}=Do(this)&&this||{},t={},n=(s,r)=>{const o=e&&Mo(t,r)||r;dn(t[o])&&dn(s)?t[o]=ms(t[o],s):dn(s)?t[o]=ms({},s):Rt(s)?t[o]=s.slice():t[o]=s};for(let s=0,r=arguments.length;s(Jt(t,(r,o)=>{n&&Ce(r)?e[o]=Io(r,n):e[o]=r},{allOwnKeys:s}),e),$c=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),kc=(e,t,n,s)=>{e.prototype=Object.create(t.prototype,s),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},Kc=(e,t,n,s)=>{let r,o,i;const l={};if(t=t||{},e==null)return t;do{for(r=Object.getOwnPropertyNames(e),o=r.length;o-- >0;)i=r[o],(!s||s(i,e,t))&&!l[i]&&(t[i]=e[i],l[i]=!0);e=n!==!1&&Ds(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},qc=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const s=e.indexOf(t,n);return s!==-1&&s===n},zc=e=>{if(!e)return null;if(Rt(e))return e;let t=e.length;if(!Uo(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},Wc=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&Ds(Uint8Array)),Jc=(e,t)=>{const s=(e&&e[Symbol.iterator]).call(e);let r;for(;(r=s.next())&&!r.done;){const o=r.value;t.call(e,o[0],o[1])}},Gc=(e,t)=>{let n;const s=[];for(;(n=e.exec(t))!==null;)s.push(n);return s},Xc=De("HTMLFormElement"),Yc=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,s,r){return s.toUpperCase()+r}),Tr=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),Qc=De("RegExp"),Bo=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),s={};Jt(n,(r,o)=>{let i;(i=t(r,o,e))!==!1&&(s[o]=i||r)}),Object.defineProperties(e,s)},Zc=e=>{Bo(e,(t,n)=>{if(Ce(e)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const s=e[n];if(Ce(s)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},eu=(e,t)=>{const n={},s=r=>{r.forEach(o=>{n[o]=!0})};return Rt(e)?s(e):s(String(e).split(t)),n},tu=()=>{},nu=(e,t)=>(e=+e,Number.isFinite(e)?e:t),es="abcdefghijklmnopqrstuvwxyz",Rr="0123456789",Ho={DIGIT:Rr,ALPHA:es,ALPHA_DIGIT:es+es.toUpperCase()+Rr},su=(e=16,t=Ho.ALPHA_DIGIT)=>{let n="";const{length:s}=t;for(;e--;)n+=t[Math.random()*s|0];return n};function ru(e){return!!(e&&Ce(e.append)&&e[Symbol.toStringTag]==="FormData"&&e[Symbol.iterator])}const ou=e=>{const t=new Array(10),n=(s,r)=>{if(Bn(s)){if(t.indexOf(s)>=0)return;if(!("toJSON"in s)){t[r]=s;const o=Rt(s)?[]:{};return Jt(s,(i,l)=>{const c=n(i,r+1);!qt(c)&&(o[l]=c)}),t[r]=void 0,o}}return s};return n(e,0)},iu=De("AsyncFunction"),lu=e=>e&&(Bn(e)||Ce(e))&&Ce(e.then)&&Ce(e.catch),m={isArray:Rt,isArrayBuffer:Lo,isBuffer:vc,isFormData:Dc,isArrayBufferView:Pc,isString:Nc,isNumber:Uo,isBoolean:Fc,isObject:Bn,isPlainObject:dn,isUndefined:qt,isDate:Ic,isFile:Lc,isBlob:Uc,isRegExp:Qc,isFunction:Ce,isStream:jc,isURLSearchParams:Bc,isTypedArray:Wc,isFileList:Mc,forEach:Jt,merge:ms,extend:Vc,trim:Hc,stripBOM:$c,inherits:kc,toFlatObject:Kc,kindOf:jn,kindOfTest:De,endsWith:qc,toArray:zc,forEachEntry:Jc,matchAll:Gc,isHTMLForm:Xc,hasOwnProperty:Tr,hasOwnProp:Tr,reduceDescriptors:Bo,freezeMethods:Zc,toObjectSet:eu,toCamelCase:Yc,noop:tu,toFiniteNumber:nu,findKey:Mo,global:jo,isContextDefined:Do,ALPHABET:Ho,generateString:su,isSpecCompliantForm:ru,toJSONObject:ou,isAsyncFn:iu,isThenable:lu};function $(e,t,n,s,r){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),s&&(this.request=s),r&&(this.response=r)}m.inherits($,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:m.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});const Vo=$.prototype,$o={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{$o[e]={value:e}});Object.defineProperties($,$o);Object.defineProperty(Vo,"isAxiosError",{value:!0});$.from=(e,t,n,s,r,o)=>{const i=Object.create(Vo);return m.toFlatObject(e,i,function(c){return c!==Error.prototype},l=>l!=="isAxiosError"),$.call(i,e.message,t,n,s,r),i.cause=e,i.name=e.name,o&&Object.assign(i,o),i};const cu=null;function gs(e){return m.isPlainObject(e)||m.isArray(e)}function ko(e){return m.endsWith(e,"[]")?e.slice(0,-2):e}function vr(e,t,n){return e?e.concat(t).map(function(r,o){return r=ko(r),!n&&o?"["+r+"]":r}).join(n?".":""):t}function uu(e){return m.isArray(e)&&!e.some(gs)}const fu=m.toFlatObject(m,{},null,function(t){return/^is[A-Z]/.test(t)});function Hn(e,t,n){if(!m.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=m.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(x,j){return!m.isUndefined(j[x])});const s=n.metaTokens,r=n.visitor||d,o=n.dots,i=n.indexes,c=(n.Blob||typeof Blob<"u"&&Blob)&&m.isSpecCompliantForm(t);if(!m.isFunction(r))throw new TypeError("visitor must be a function");function a(A){if(A===null)return"";if(m.isDate(A))return A.toISOString();if(!c&&m.isBlob(A))throw new $("Blob is not supported. Use a Buffer instead.");return m.isArrayBuffer(A)||m.isTypedArray(A)?c&&typeof Blob=="function"?new Blob([A]):Buffer.from(A):A}function d(A,x,j){let L=A;if(A&&!j&&typeof A=="object"){if(m.endsWith(x,"{}"))x=s?x:x.slice(0,-2),A=JSON.stringify(A);else if(m.isArray(A)&&uu(A)||(m.isFileList(A)||m.endsWith(x,"[]"))&&(L=m.toArray(A)))return x=ko(x),L.forEach(function(D,J){!(m.isUndefined(D)||D===null)&&t.append(i===!0?vr([x],J,o):i===null?x:x+"[]",a(D))}),!1}return gs(A)?!0:(t.append(vr(j,x,o),a(A)),!1)}const h=[],O=Object.assign(fu,{defaultVisitor:d,convertValue:a,isVisitable:gs});function P(A,x){if(!m.isUndefined(A)){if(h.indexOf(A)!==-1)throw Error("Circular reference detected in "+x.join("."));h.push(A),m.forEach(A,function(L,oe){(!(m.isUndefined(L)||L===null)&&r.call(t,L,m.isString(oe)?oe.trim():oe,x,O))===!0&&P(L,x?x.concat(oe):[oe])}),h.pop()}}if(!m.isObject(e))throw new TypeError("data must be an object");return P(e),t}function Pr(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(s){return t[s]})}function Bs(e,t){this._pairs=[],e&&Hn(e,this,t)}const Ko=Bs.prototype;Ko.append=function(t,n){this._pairs.push([t,n])};Ko.toString=function(t){const n=t?function(s){return t.call(this,s,Pr)}:Pr;return this._pairs.map(function(r){return n(r[0])+"="+n(r[1])},"").join("&")};function au(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function qo(e,t,n){if(!t)return e;const s=n&&n.encode||au,r=n&&n.serialize;let o;if(r?o=r(t,n):o=m.isURLSearchParams(t)?t.toString():new Bs(t,n).toString(s),o){const i=e.indexOf("#");i!==-1&&(e=e.slice(0,i)),e+=(e.indexOf("?")===-1?"?":"&")+o}return e}class Nr{constructor(){this.handlers=[]}use(t,n,s){return this.handlers.push({fulfilled:t,rejected:n,synchronous:s?s.synchronous:!1,runWhen:s?s.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){m.forEach(this.handlers,function(s){s!==null&&t(s)})}}const zo={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},du=typeof URLSearchParams<"u"?URLSearchParams:Bs,hu=typeof FormData<"u"?FormData:null,pu=typeof Blob<"u"?Blob:null,mu={isBrowser:!0,classes:{URLSearchParams:du,FormData:hu,Blob:pu},protocols:["http","https","file","blob","url","data"]},Wo=typeof window<"u"&&typeof document<"u",gu=(e=>Wo&&["ReactNative","NativeScript","NS"].indexOf(e)<0)(typeof navigator<"u"&&navigator.product),_u=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",yu=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Wo,hasStandardBrowserEnv:gu,hasStandardBrowserWebWorkerEnv:_u},Symbol.toStringTag,{value:"Module"})),je={...yu,...mu};function bu(e,t){return Hn(e,new je.classes.URLSearchParams,Object.assign({visitor:function(n,s,r,o){return je.isNode&&m.isBuffer(n)?(this.append(s,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)}},t))}function wu(e){return m.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function Eu(e){const t={},n=Object.keys(e);let s;const r=n.length;let o;for(s=0;s=n.length;return i=!i&&m.isArray(r)?r.length:i,c?(m.hasOwnProp(r,i)?r[i]=[r[i],s]:r[i]=s,!l):((!r[i]||!m.isObject(r[i]))&&(r[i]=[]),t(n,s,r[i],o)&&m.isArray(r[i])&&(r[i]=Eu(r[i])),!l)}if(m.isFormData(e)&&m.isFunction(e.entries)){const n={};return m.forEachEntry(e,(s,r)=>{t(wu(s),r,n,0)}),n}return null}function xu(e,t,n){if(m.isString(e))try{return(t||JSON.parse)(e),m.trim(e)}catch(s){if(s.name!=="SyntaxError")throw s}return(n||JSON.stringify)(e)}const Hs={transitional:zo,adapter:["xhr","http"],transformRequest:[function(t,n){const s=n.getContentType()||"",r=s.indexOf("application/json")>-1,o=m.isObject(t);if(o&&m.isHTMLForm(t)&&(t=new FormData(t)),m.isFormData(t))return r?JSON.stringify(Jo(t)):t;if(m.isArrayBuffer(t)||m.isBuffer(t)||m.isStream(t)||m.isFile(t)||m.isBlob(t))return t;if(m.isArrayBufferView(t))return t.buffer;if(m.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let l;if(o){if(s.indexOf("application/x-www-form-urlencoded")>-1)return bu(t,this.formSerializer).toString();if((l=m.isFileList(t))||s.indexOf("multipart/form-data")>-1){const c=this.env&&this.env.FormData;return Hn(l?{"files[]":t}:t,c&&new c,this.formSerializer)}}return o||r?(n.setContentType("application/json",!1),xu(t)):t}],transformResponse:[function(t){const n=this.transitional||Hs.transitional,s=n&&n.forcedJSONParsing,r=this.responseType==="json";if(t&&m.isString(t)&&(s&&!this.responseType||r)){const i=!(n&&n.silentJSONParsing)&&r;try{return JSON.parse(t)}catch(l){if(i)throw l.name==="SyntaxError"?$.from(l,$.ERR_BAD_RESPONSE,this,null,this.response):l}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:je.classes.FormData,Blob:je.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};m.forEach(["delete","get","head","post","put","patch"],e=>{Hs.headers[e]={}});const Vs=Hs,Su=m.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Ou=e=>{const t={};let n,s,r;return e&&e.split(` 18 | `).forEach(function(i){r=i.indexOf(":"),n=i.substring(0,r).trim().toLowerCase(),s=i.substring(r+1).trim(),!(!n||t[n]&&Su[n])&&(n==="set-cookie"?t[n]?t[n].push(s):t[n]=[s]:t[n]=t[n]?t[n]+", "+s:s)}),t},Fr=Symbol("internals");function It(e){return e&&String(e).trim().toLowerCase()}function hn(e){return e===!1||e==null?e:m.isArray(e)?e.map(hn):String(e)}function Cu(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let s;for(;s=n.exec(e);)t[s[1]]=s[2];return t}const Au=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function ts(e,t,n,s,r){if(m.isFunction(s))return s.call(this,t,n);if(r&&(t=n),!!m.isString(t)){if(m.isString(s))return t.indexOf(s)!==-1;if(m.isRegExp(s))return s.test(t)}}function Tu(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,s)=>n.toUpperCase()+s)}function Ru(e,t){const n=m.toCamelCase(" "+t);["get","set","has"].forEach(s=>{Object.defineProperty(e,s+n,{value:function(r,o,i){return this[s].call(this,t,r,o,i)},configurable:!0})})}class Vn{constructor(t){t&&this.set(t)}set(t,n,s){const r=this;function o(l,c,a){const d=It(c);if(!d)throw new Error("header name must be a non-empty string");const h=m.findKey(r,d);(!h||r[h]===void 0||a===!0||a===void 0&&r[h]!==!1)&&(r[h||c]=hn(l))}const i=(l,c)=>m.forEach(l,(a,d)=>o(a,d,c));return m.isPlainObject(t)||t instanceof this.constructor?i(t,n):m.isString(t)&&(t=t.trim())&&!Au(t)?i(Ou(t),n):t!=null&&o(n,t,s),this}get(t,n){if(t=It(t),t){const s=m.findKey(this,t);if(s){const r=this[s];if(!n)return r;if(n===!0)return Cu(r);if(m.isFunction(n))return n.call(this,r,s);if(m.isRegExp(n))return n.exec(r);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=It(t),t){const s=m.findKey(this,t);return!!(s&&this[s]!==void 0&&(!n||ts(this,this[s],s,n)))}return!1}delete(t,n){const s=this;let r=!1;function o(i){if(i=It(i),i){const l=m.findKey(s,i);l&&(!n||ts(s,s[l],l,n))&&(delete s[l],r=!0)}}return m.isArray(t)?t.forEach(o):o(t),r}clear(t){const n=Object.keys(this);let s=n.length,r=!1;for(;s--;){const o=n[s];(!t||ts(this,this[o],o,t,!0))&&(delete this[o],r=!0)}return r}normalize(t){const n=this,s={};return m.forEach(this,(r,o)=>{const i=m.findKey(s,o);if(i){n[i]=hn(r),delete n[o];return}const l=t?Tu(o):String(o).trim();l!==o&&delete n[o],n[l]=hn(r),s[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return m.forEach(this,(s,r)=>{s!=null&&s!==!1&&(n[r]=t&&m.isArray(s)?s.join(", "):s)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` 19 | `)}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const s=new this(t);return n.forEach(r=>s.set(r)),s}static accessor(t){const s=(this[Fr]=this[Fr]={accessors:{}}).accessors,r=this.prototype;function o(i){const l=It(i);s[l]||(Ru(r,i),s[l]=!0)}return m.isArray(t)?t.forEach(o):o(t),this}}Vn.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);m.reduceDescriptors(Vn.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(s){this[n]=s}}});m.freezeMethods(Vn);const Ke=Vn;function ns(e,t){const n=this||Vs,s=t||n,r=Ke.from(s.headers);let o=s.data;return m.forEach(e,function(l){o=l.call(n,o,r.normalize(),t?t.status:void 0)}),r.normalize(),o}function Go(e){return!!(e&&e.__CANCEL__)}function Gt(e,t,n){$.call(this,e??"canceled",$.ERR_CANCELED,t,n),this.name="CanceledError"}m.inherits(Gt,$,{__CANCEL__:!0});function vu(e,t,n){const s=n.config.validateStatus;!n.status||!s||s(n.status)?e(n):t(new $("Request failed with status code "+n.status,[$.ERR_BAD_REQUEST,$.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}const Pu=je.hasStandardBrowserEnv?{write(e,t,n,s,r,o){const i=[e+"="+encodeURIComponent(t)];m.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),m.isString(s)&&i.push("path="+s),m.isString(r)&&i.push("domain="+r),o===!0&&i.push("secure"),document.cookie=i.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function Nu(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function Fu(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function Xo(e,t){return e&&!Nu(t)?Fu(e,t):t}const Iu=je.hasStandardBrowserEnv?function(){const t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");let s;function r(o){let i=o;return t&&(n.setAttribute("href",i),i=n.href),n.setAttribute("href",i),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:n.pathname.charAt(0)==="/"?n.pathname:"/"+n.pathname}}return s=r(window.location.href),function(i){const l=m.isString(i)?r(i):i;return l.protocol===s.protocol&&l.host===s.host}}():function(){return function(){return!0}}();function Lu(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function Uu(e,t){e=e||10;const n=new Array(e),s=new Array(e);let r=0,o=0,i;return t=t!==void 0?t:1e3,function(c){const a=Date.now(),d=s[o];i||(i=a),n[r]=c,s[r]=a;let h=o,O=0;for(;h!==r;)O+=n[h++],h=h%e;if(r=(r+1)%e,r===o&&(o=(o+1)%e),a-i{const o=r.loaded,i=r.lengthComputable?r.total:void 0,l=o-n,c=s(l),a=o<=i;n=o;const d={loaded:o,total:i,progress:i?o/i:void 0,bytes:l,rate:c||void 0,estimated:c&&i&&a?(i-o)/c:void 0,event:r};d[t?"download":"upload"]=!0,e(d)}}const Mu=typeof XMLHttpRequest<"u",ju=Mu&&function(e){return new Promise(function(n,s){let r=e.data;const o=Ke.from(e.headers).normalize();let{responseType:i,withXSRFToken:l}=e,c;function a(){e.cancelToken&&e.cancelToken.unsubscribe(c),e.signal&&e.signal.removeEventListener("abort",c)}let d;if(m.isFormData(r)){if(je.hasStandardBrowserEnv||je.hasStandardBrowserWebWorkerEnv)o.setContentType(!1);else if((d=o.getContentType())!==!1){const[x,...j]=d?d.split(";").map(L=>L.trim()).filter(Boolean):[];o.setContentType([x||"multipart/form-data",...j].join("; "))}}let h=new XMLHttpRequest;if(e.auth){const x=e.auth.username||"",j=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";o.set("Authorization","Basic "+btoa(x+":"+j))}const O=Xo(e.baseURL,e.url);h.open(e.method.toUpperCase(),qo(O,e.params,e.paramsSerializer),!0),h.timeout=e.timeout;function P(){if(!h)return;const x=Ke.from("getAllResponseHeaders"in h&&h.getAllResponseHeaders()),L={data:!i||i==="text"||i==="json"?h.responseText:h.response,status:h.status,statusText:h.statusText,headers:x,config:e,request:h};vu(function(D){n(D),a()},function(D){s(D),a()},L),h=null}if("onloadend"in h?h.onloadend=P:h.onreadystatechange=function(){!h||h.readyState!==4||h.status===0&&!(h.responseURL&&h.responseURL.indexOf("file:")===0)||setTimeout(P)},h.onabort=function(){h&&(s(new $("Request aborted",$.ECONNABORTED,e,h)),h=null)},h.onerror=function(){s(new $("Network Error",$.ERR_NETWORK,e,h)),h=null},h.ontimeout=function(){let j=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const L=e.transitional||zo;e.timeoutErrorMessage&&(j=e.timeoutErrorMessage),s(new $(j,L.clarifyTimeoutError?$.ETIMEDOUT:$.ECONNABORTED,e,h)),h=null},je.hasStandardBrowserEnv&&(l&&m.isFunction(l)&&(l=l(e)),l||l!==!1&&Iu(O))){const x=e.xsrfHeaderName&&e.xsrfCookieName&&Pu.read(e.xsrfCookieName);x&&o.set(e.xsrfHeaderName,x)}r===void 0&&o.setContentType(null),"setRequestHeader"in h&&m.forEach(o.toJSON(),function(j,L){h.setRequestHeader(L,j)}),m.isUndefined(e.withCredentials)||(h.withCredentials=!!e.withCredentials),i&&i!=="json"&&(h.responseType=e.responseType),typeof e.onDownloadProgress=="function"&&h.addEventListener("progress",Ir(e.onDownloadProgress,!0)),typeof e.onUploadProgress=="function"&&h.upload&&h.upload.addEventListener("progress",Ir(e.onUploadProgress)),(e.cancelToken||e.signal)&&(c=x=>{h&&(s(!x||x.type?new Gt(null,e,h):x),h.abort(),h=null)},e.cancelToken&&e.cancelToken.subscribe(c),e.signal&&(e.signal.aborted?c():e.signal.addEventListener("abort",c)));const A=Lu(O);if(A&&je.protocols.indexOf(A)===-1){s(new $("Unsupported protocol "+A+":",$.ERR_BAD_REQUEST,e));return}h.send(r||null)})},_s={http:cu,xhr:ju};m.forEach(_s,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const Lr=e=>`- ${e}`,Du=e=>m.isFunction(e)||e===null||e===!1,Yo={getAdapter:e=>{e=m.isArray(e)?e:[e];const{length:t}=e;let n,s;const r={};for(let o=0;o`adapter ${l} `+(c===!1?"is not supported by the environment":"is not available in the build"));let i=t?o.length>1?`since : 20 | `+o.map(Lr).join(` 21 | `):" "+Lr(o[0]):"as no adapter specified";throw new $("There is no suitable adapter to dispatch the request "+i,"ERR_NOT_SUPPORT")}return s},adapters:_s};function ss(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Gt(null,e)}function Ur(e){return ss(e),e.headers=Ke.from(e.headers),e.data=ns.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),Yo.getAdapter(e.adapter||Vs.adapter)(e).then(function(s){return ss(e),s.data=ns.call(e,e.transformResponse,s),s.headers=Ke.from(s.headers),s},function(s){return Go(s)||(ss(e),s&&s.response&&(s.response.data=ns.call(e,e.transformResponse,s.response),s.response.headers=Ke.from(s.response.headers))),Promise.reject(s)})}const Mr=e=>e instanceof Ke?{...e}:e;function At(e,t){t=t||{};const n={};function s(a,d,h){return m.isPlainObject(a)&&m.isPlainObject(d)?m.merge.call({caseless:h},a,d):m.isPlainObject(d)?m.merge({},d):m.isArray(d)?d.slice():d}function r(a,d,h){if(m.isUndefined(d)){if(!m.isUndefined(a))return s(void 0,a,h)}else return s(a,d,h)}function o(a,d){if(!m.isUndefined(d))return s(void 0,d)}function i(a,d){if(m.isUndefined(d)){if(!m.isUndefined(a))return s(void 0,a)}else return s(void 0,d)}function l(a,d,h){if(h in t)return s(a,d);if(h in e)return s(void 0,a)}const c={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:l,headers:(a,d)=>r(Mr(a),Mr(d),!0)};return m.forEach(Object.keys(Object.assign({},e,t)),function(d){const h=c[d]||r,O=h(e[d],t[d],d);m.isUndefined(O)&&h!==l||(n[d]=O)}),n}const Qo="1.6.8",$s={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{$s[e]=function(s){return typeof s===e||"a"+(t<1?"n ":" ")+e}});const jr={};$s.transitional=function(t,n,s){function r(o,i){return"[Axios v"+Qo+"] Transitional option '"+o+"'"+i+(s?". "+s:"")}return(o,i,l)=>{if(t===!1)throw new $(r(i," has been removed"+(n?" in "+n:"")),$.ERR_DEPRECATED);return n&&!jr[i]&&(jr[i]=!0,console.warn(r(i," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,i,l):!0}};function Bu(e,t,n){if(typeof e!="object")throw new $("options must be an object",$.ERR_BAD_OPTION_VALUE);const s=Object.keys(e);let r=s.length;for(;r-- >0;){const o=s[r],i=t[o];if(i){const l=e[o],c=l===void 0||i(l,o,e);if(c!==!0)throw new $("option "+o+" must be "+c,$.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new $("Unknown option "+o,$.ERR_BAD_OPTION)}}const ys={assertOptions:Bu,validators:$s},Ge=ys.validators;class xn{constructor(t){this.defaults=t,this.interceptors={request:new Nr,response:new Nr}}async request(t,n){try{return await this._request(t,n)}catch(s){if(s instanceof Error){let r;Error.captureStackTrace?Error.captureStackTrace(r={}):r=new Error;const o=r.stack?r.stack.replace(/^.+\n/,""):"";s.stack?o&&!String(s.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(s.stack+=` 22 | `+o):s.stack=o}throw s}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=At(this.defaults,n);const{transitional:s,paramsSerializer:r,headers:o}=n;s!==void 0&&ys.assertOptions(s,{silentJSONParsing:Ge.transitional(Ge.boolean),forcedJSONParsing:Ge.transitional(Ge.boolean),clarifyTimeoutError:Ge.transitional(Ge.boolean)},!1),r!=null&&(m.isFunction(r)?n.paramsSerializer={serialize:r}:ys.assertOptions(r,{encode:Ge.function,serialize:Ge.function},!0)),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&m.merge(o.common,o[n.method]);o&&m.forEach(["delete","get","head","post","put","patch","common"],A=>{delete o[A]}),n.headers=Ke.concat(i,o);const l=[];let c=!0;this.interceptors.request.forEach(function(x){typeof x.runWhen=="function"&&x.runWhen(n)===!1||(c=c&&x.synchronous,l.unshift(x.fulfilled,x.rejected))});const a=[];this.interceptors.response.forEach(function(x){a.push(x.fulfilled,x.rejected)});let d,h=0,O;if(!c){const A=[Ur.bind(this),void 0];for(A.unshift.apply(A,l),A.push.apply(A,a),O=A.length,d=Promise.resolve(n);h{if(!s._listeners)return;let o=s._listeners.length;for(;o-- >0;)s._listeners[o](r);s._listeners=null}),this.promise.then=r=>{let o;const i=new Promise(l=>{s.subscribe(l),o=l}).then(r);return i.cancel=function(){s.unsubscribe(o)},i},t(function(o,i,l){s.reason||(s.reason=new Gt(o,i,l),n(s.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}static source(){let t;return{token:new ks(function(r){t=r}),cancel:t}}}const Hu=ks;function Vu(e){return function(n){return e.apply(null,n)}}function $u(e){return m.isObject(e)&&e.isAxiosError===!0}const bs={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(bs).forEach(([e,t])=>{bs[t]=e});const ku=bs;function Zo(e){const t=new pn(e),n=Io(pn.prototype.request,t);return m.extend(n,pn.prototype,t,{allOwnKeys:!0}),m.extend(n,t,null,{allOwnKeys:!0}),n.create=function(r){return Zo(At(e,r))},n}const q=Zo(Vs);q.Axios=pn;q.CanceledError=Gt;q.CancelToken=Hu;q.isCancel=Go;q.VERSION=Qo;q.toFormData=Hn;q.AxiosError=$;q.Cancel=q.CanceledError;q.all=function(t){return Promise.all(t)};q.spread=Vu;q.isAxiosError=$u;q.mergeConfig=At;q.AxiosHeaders=Ke;q.formToJSON=e=>Jo(m.isHTMLForm(e)?new FormData(e):e);q.getAdapter=Yo.getAdapter;q.HttpStatusCode=ku;q.default=q;class Ku{constructor(){Qt(this,"speaker","");Qt(this,"emotion","");Qt(this,"character","")}}const W=e=>(Ji("data-v-fba62608"),e=e(),Gi(),e),qu={class:"container"},zu=W(()=>E("h1",null,"第一步",-1)),Wu=W(()=>E("p",null," 本步骤的作用是对白菜工厂1145号员工大佬分享的模型匹配生成infer_config.json配置文件,使之可以被GPTS-SOVITS-Interface识别 ",-1)),Ju=W(()=>E("p",{style:{"font-weight":"500",color:"red"}}," 如果模型来源不是其分享,请不要执行该操作。否则会导致错误的infer_config.json文件生成 ",-1)),Gu=W(()=>E("p",null," 输入的位置为模型文件夹所在的上一级文件夹,如E:\\GPT-Sovits\\GPT-SoVITS-Inference\\trained(注意不要携带双引号) ",-1)),Xu=W(()=>E("p",{style:{"font-weight":"500",color:"red"}}," 注意:该指令仅需执行一次,已经存在infer_config.json配置文件不需要再执行! ",-1)),Yu=W(()=>E("hr",null,null,-1)),Qu=W(()=>E("h1",null,"第二步",-1)),Zu=W(()=>E("p",null," 本步骤作用是对小说txt文件进行切分,每一章会切分为一个txt文件,储存在提交文件路径的同级同名文件夹下 ",-1)),ef=W(()=>E("p",{style:{"font-weight":"500",color:"red"}}," 注意,切分是以  第xxx章 xxx  进行正则匹配的,所以不符合格式的小说将无法切分成功 ",-1)),tf=W(()=>E("p",null," 输入位置如(注意不要携带双引号): E:\\有声书\\深海余烬.txt    切分后文件位置 :E:\\有声书\\深海余烬 ",-1)),nf=W(()=>E("hr",null,null,-1)),sf=W(()=>E("h1",null,"第三步",-1)),rf=W(()=>E("p",null,"本步骤作用是填写语音生成的默认配置",-1)),of=W(()=>E("label",null,"请输入后端url,末尾要带上/",-1)),lf=W(()=>E("label",null,"默认语速",-1)),cf=W(()=>E("label",null,"默认batch_size",-1)),uf=W(()=>E("br",null,null,-1)),ff=W(()=>E("label",null,"默认旁白朗读角色",-1)),af=["value"],df=W(()=>E("label",null,"默认旁白朗读情感",-1)),hf=["value"],pf=W(()=>E("br",null,null,-1)),mf=W(()=>E("label",null,"默认对话朗读角色",-1)),gf=["value"],_f=W(()=>E("label",null,"默认对话朗读情感",-1)),yf=["value"],bf=W(()=>E("br",null,null,-1)),wf=W(()=>E("h1",null,"第四步",-1)),Ef=W(()=>E("p",null,"添加小说中的角色及模型绑定",-1)),xf=["value"],Sf=["value"],Of=W(()=>E("thead",null,[E("tr",null,[E("th",null,"小说角色"),E("th",null,"配音角色"),E("th",null,"情感"),E("th",null,"操作")])],-1)),Cf=["onClick"],Af=W(()=>E("h1",null,"第五步",-1)),Tf=W(()=>E("p",null,"本步骤作用修改对应章节有声书的生成信息",-1)),Rf=W(()=>E("label",null,"请选择章节",-1)),vf=["value"],Pf={class:"article"},Nf={class:"info"},Ff=["onUpdate:modelValue","onChange"],If=["value"],Lf=["onUpdate:modelValue","onChange"],Uf=["value"],Mf=["onUpdate:modelValue","onInput"],jf=W(()=>E("h1",null,"第七步",-1)),Df=W(()=>E("p",null,"转化之前储存的小说",-1)),Bf=ll({__name:"App",setup(e){let t="",n="",s=Je([]),r,o,i,l=Je([]),c,a,d,h,O=Je([]),P=Je([]),A,x,j,L=Je([]),oe=Je([]),D,J=Je([]),Q="http://localhost:8000/handle",V=Je(new Map);bo(async()=>{await Pt(),await Ve(),await Z(),await G(),a=c=s.value[0],ze(),st()});function Ae(F){q.delete(Q+"/deleteConfig",{params:{speaker:L.value[F].speaker}}),L.value.splice(F,1)}function Se(F,v){console.log(F),J.value[v].speed=F}async function vt(){let F=await q.post(Q+"/saveFormatArticle",{sentenceInfo:J.value,novelName:D});alert(F.data.message)}function Be(){q.get(Q+"/novelTTS"),alert("以开始转化,查看文件夹或控制面板获取输出详情")}function ze(){console.log(c),O.value=_e(c),console.log(O.value),d=O.value[0]}function st(){console.log(a),P.value=_e(a),console.log(P.value),h=P.value[0]}function mt(){l.value=_e(o),i=l.value[0]}async function Pt(){let F=await q.get(Q+"/getAllCharacterAndEmotion");V.value=new Map(Object.entries(F.data.data.characterInConfig))}async function Xt(){let F=await q.get(Q+"/getHandledArticle",{params:{articleName:D}});J.value=F.data.data.sentenceInfos,console.log(J.value)}function ae(F,v){let y=v.target.value;J.value[F].emotion=y}async function Z(){let F=await q.get(Q+"/getBundleConfig");L.value=F.data.data.speakerInfos}async function G(){let F=await q.get(Q+"/getArticleList");oe.value=F.data.data.getArticleList,console.log(oe.value)}async function He(){if(t==""){alert("模型文件位置不能为空");return}let F=await q.get(Q+"/handleModelConfig",{params:{modelPath:t}});alert(F.data.message)}async function gt(){if(n==""){alert("小说文件位置不能为空");return}if(!n.endsWith(".txt")){alert("小说文件类型需为txt");return}let F=await q.get(Q+"/splitArticle",{params:{novelPath:n}});alert(F.data.message)}async function Ve(){let F=await q.get(Q+"/getAllCharacter");s.value=F.data.data.characterList}function _e(F){return V.value.get(F)}async function Yt(){if(j==""){alert("url不能为空");return}let F=new Map;F.set("url",j),F.set("speed",A),F.set("batchSize",x),F.set("defaultDialogueCharacter",c),F.set("defaultDialogueEmotion",d),F.set("defaultNarrationCharacter",a),F.set("defaultNarrationEmotion",h);let v=Object.fromEntries(F),y=await q.put(Q+"/addConfig",v);alert(y.data.message)}function $n(F,v){const y=v.target;J.value[F].speaker=y.value;let K=L.value.findIndex(ee=>ee.speaker===y.value);J.value[F].character=L.value[K].character,J.value[F].emotion=L.value[K].emotion}function kn(){if(o==""){alert("小说角色不能为空");return}let F=new Ku,v=L.value.findIndex(y=>y.speaker===r);v!==-1&&L.value.splice(v,1),F.speaker=r,F.character=o,F.emotion=i,L.value.push(F)}async function Te(){let F=await q.put(Q+"/addBundleConfig",L.value);alert(F.data.message)}return(F,v)=>(ie(),le("div",qu,[E("div",null,[zu,Wu,Ju,Gu,Xu,Yu,he(E("input",{"onUpdate:modelValue":v[0]||(v[0]=y=>Y(t)?t.value=y:t=y),placeholder:"请输入模型文件位置"},null,512),[[it,te(t)]]),E("button",{onClick:v[1]||(v[1]=y=>He())},"进行配置文件转化")]),E("div",null,[Qu,Zu,ef,tf,nf,he(E("input",{"onUpdate:modelValue":v[2]||(v[2]=y=>Y(n)?n.value=y:n=y),placeholder:"请输入小说文件位置"},null,512),[[it,te(n)]]),E("button",{onClick:v[3]||(v[3]=y=>gt())},"进行小说文件切分")]),E("div",null,[sf,rf,E("div",null,[of,he(E("input",{"onUpdate:modelValue":v[4]||(v[4]=y=>Y(j)?j.value=y:j=y),placeholder:"如http://127.0.0.1:6006/"},null,512),[[it,te(j)]])]),E("div",null,[lf,he(E("input",{"onUpdate:modelValue":v[5]||(v[5]=y=>Y(A)?A.value=y:A=y),placeholder:"请输入语速,默认1.0"},null,512),[[it,te(A)]]),cf,he(E("input",{"onUpdate:modelValue":v[6]||(v[6]=y=>Y(x)?x.value=y:x=y),placeholder:"整数,默认10,越大生成越快,但电脑性能要求越高"},null,512),[[it,te(x)]])]),uf,E("div",null,[ff,he(E("select",{"onUpdate:modelValue":v[7]||(v[7]=y=>Y(a)?a.value=y:a=y),onChange:v[8]||(v[8]=y=>st())},[(ie(!0),le(ce,null,ve(te(s),(y,K)=>(ie(),le("option",{key:K,value:y},ye(y),9,af))),128))],544),[[$e,te(a)]]),df,he(E("select",{"onUpdate:modelValue":v[9]||(v[9]=y=>Y(h)?h.value=y:h=y)},[(ie(!0),le(ce,null,ve(te(P),(y,K)=>(ie(),le("option",{key:K,value:y},ye(y),9,hf))),128))],512),[[$e,te(h)]])]),pf,E("div",null,[mf,he(E("select",{"onUpdate:modelValue":v[10]||(v[10]=y=>Y(c)?c.value=y:c=y),onChange:v[11]||(v[11]=y=>ze())},[(ie(!0),le(ce,null,ve(te(s),(y,K)=>(ie(),le("option",{key:K,value:y},ye(y),9,gf))),128))],544),[[$e,te(c)]]),_f,he(E("select",{"onUpdate:modelValue":v[12]||(v[12]=y=>Y(d)?d.value=y:d=y)},[(ie(!0),le(ce,null,ve(te(O),(y,K)=>(ie(),le("option",{key:K,value:y},ye(y),9,yf))),128))],512),[[$e,te(d)]]),bf,E("button",{onClick:v[13]||(v[13]=y=>Yt())},"确认提交")])]),E("div",null,[wf,Ef,E("div",null,[he(E("input",{"onUpdate:modelValue":v[14]||(v[14]=y=>Y(r)?r.value=y:r=y),style:{width:"200px"},placeholder:"请输入小说角色"},null,512),[[it,te(r)]]),he(E("select",{"onUpdate:modelValue":v[15]||(v[15]=y=>Y(o)?o.value=y:o=y),onChange:v[16]||(v[16]=y=>mt())},[(ie(!0),le(ce,null,ve(te(s),(y,K)=>(ie(),le("option",{key:K,value:y},ye(y),9,xf))),128))],544),[[$e,te(o)]]),he(E("select",{"onUpdate:modelValue":v[17]||(v[17]=y=>Y(i)?i.value=y:i=y)},[(ie(!0),le(ce,null,ve(te(l),(y,K)=>(ie(),le("option",{key:K,value:y},ye(y),9,Sf))),128))],512),[[$e,te(i)]]),E("button",{onClick:v[18]||(v[18]=y=>kn())},"添加")]),E("table",null,[Of,E("tbody",null,[(ie(!0),le(ce,null,ve(te(L),(y,K)=>(ie(),le("tr",{key:K},[E("td",null,ye(y.speaker),1),E("td",null,ye(y.character),1),E("td",null,ye(y.emotion),1),E("td",null,[E("button",{onClick:ee=>Ae(K)},"删除",8,Cf)])]))),128))])]),E("button",{onClick:v[19]||(v[19]=y=>Te())},"提交绑定关系")]),E("div",null,[E("div",null,[Af,Tf,Rf,he(E("select",{"onUpdate:modelValue":v[20]||(v[20]=y=>Y(D)?D.value=y:D=y),onClick:v[21]||(v[21]=y=>Xt())},[(ie(!0),le(ce,null,ve(te(oe),(y,K)=>(ie(),le("option",{key:K,value:y},ye(y),9,vf))),128))],512),[[$e,te(D)]])]),E("div",Pf,[(ie(!0),le(ce,null,ve(te(J),(y,K)=>(ie(),le("div",{style:{"border-bottom":"red 2px solid"},key:K,class:"item"},[E("div",{class:An([{"red-text":y.dialogue},"sentence"])},ye(y.sentence),3),E("div",Nf,[he(E("select",{"onUpdate:modelValue":ee=>y.speaker=ee,onChange:ee=>$n(K,ee)},[(ie(!0),le(ce,null,ve(te(L),ee=>(ie(),le("option",{key:ee.speaker,value:ee.speaker},ye(ee.speaker),9,If))),128))],40,Ff),[[$e,y.speaker]]),E("div",null,"   配音角色:"+ye(y.character),1),E("div",null,[he(E("select",{"onUpdate:modelValue":ee=>y.emotion=ee,onChange:ee=>ae(K,ee)},[(ie(!0),le(ce,null,ve(te(V).get(y.character),ee=>(ie(),le("option",{key:ee,value:ee},ye(ee),9,Uf))),128))],40,Lf),[[$e,y.emotion]])]),he(E("input",{type:"number","onUpdate:modelValue":ee=>y.speed=ee,step:"0.1",min:"0",onInput:ee=>Se(y.speed,K)},null,40,Mf),[[it,y.speed]])])]))),128))]),E("button",{onClick:v[22]||(v[22]=y=>vt())},"储存修改后的小说信息")]),E("div",null,[jf,Df,E("button",{onClick:v[23]||(v[23]=y=>Be())},"点击转化")])]))}}),Hf=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},Vf=Hf(Bf,[["__scopeId","data-v-fba62608"]]);Cc(Vf).mount("#app"); 23 | -------------------------------------------------------------------------------- /src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qumingzhentmdnan/NovelTTS/62e665ece1c5eda72c4cc1d31a791b0d95541067/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | --------------------------------------------------------------------------------